第 1 類:spa
普通類A的 普通類B 友元(一對一友好關係):code
無需前置聲明class B,當class B第一次出如今friend聲明中時,該名字被隱式地認爲可見。blog
class A { friend class B; public: void f() { cout << "class A"; } private: int a; }; class B { public: void f() { cout << "class B"; } void accessA(A& a) { cout << a.a; } };
第 2 類:編譯器
普通類A的 實例化了的模板類B 友元(一對一友好關係):編譯
若是普通類A的友元是一個實例化了的特定模板,那麼這個具體實例化了的類在被聲明爲友元時,正如使用vector同樣,要帶具體的類型參數,如vector<int>,因此是friend class B<int>,可是和前面一種聲明相比,編譯器在讀取class B<int>以爲很怪異,不知道這個<int>是什麼東西,所以會報錯,爲了讓編譯器認識它,知道它是個實例化了的模板,必須在class聲明以前先提早告知編譯器class B本來是個模板,friend聲明友元時代表了這是某一個具體模板實例。模板
template <typename> class B; class A { friend class B<int>; public: void f() { cout << "class A"; } private: int a; }; template <typename T> class B { public: void f() { cout << "class B"; } void accessA(A& a) { cout << a.a; } };
第 3 類:class
普通類A的 模板類B 友元(一對多友好關係):di
這裏普通類class A的友元是模板class B,而不是某一個具體實例化了的class B<>,只要是這個模板實例化出來的B都是A的友元。co
class A { template <typename T> friend class B; public: void f() { cout << "class A"; } private: int a; }; template <typename T> class B { public: void f() { cout << "class B"; } void accessA(A& a) { cout << a.a; } };
第 4 類:參數
實例化模板類A的 實例化模板類B 友元(一對一友好關係):
同第2類類似,這裏模板類A的友元類B也是一個模板,爲了讓編譯器認識,必須得提早聲明其是模板。且class A和class B使用相同模板類型參數,所以他們在使用相同類型實例化後獲得的實例類是對應類型的一對一友好關係。
template <typename>class B; template <typename T> class A { friend class B<T>; public: void f() { cout << "class A"; } private: T a; }; template <typename U> class B { public: void f() { cout << "class B"; } void accessA(A<U>& a) { cout << a.a; } };
第 5 類:
模板類A的 實例化模板類B 友元(多對一友好關係):
同第2類類似,這裏模板類A的友元類B也是一個模板,爲了讓編譯器認識,必須得提早聲明其是模板。B是一個特定的實例化了的模板類,它是任意模板A實例化後的友元。
template <typename> class B; template <typename T> class A { friend class B<int>; public: void f() { cout << "class A"; } private: T a; }; template <typename U> class B { public: void f() { cout << "class B"; } void accessA(A<U>& a) { cout << a.a; } };
第 6 類:
任意實例化模板類A的 模板類B 友元(多對多友好關係):
任意一個實例化的A對任意實例化的B都是友好關係。
template <typename T> class A { template <typename X> friend class B; public: void f() { cout << "class A"; } private: T a; }; template <typename U> class B { public: void f() { cout << "class B"; } void accessA(A<U>& a) { cout << a.a; } };
存在模板類A的某一特定實例化對模板類B的任意實例化都是友好關係的說明嗎?回答是不存在。由於實例化A時,A必然已經定義過了,對於一個定義過了的模板,再去添加模板的友元,這是個悖論。