關於類模板的友元函數

轉載html

http://blog.sina.com.cn/s/blog_69dd1a090101fc59.html數據結構

問題始於學習數據結構,本身編寫一個單鏈表,其中用到了重載輸出運算符<<,我寫的大約這樣:函數

1 template <class T> class List{
2     friend std::ostream& operator << (std::ostream& os,const List<T>& slist);
3     //……
4 };

用vs2008可編譯,但沒法連接:沒法解析的外部符號……學習

後來上網查改成spa

1 template <class T> class List{
2     friend std::ostream& operator <<  <>(std::ostream& os,const List<T>& slist);
3     //……
4 };

 

就能夠了。不知因此然,查了下《C++ Primer》才弄明白。code

在類模板中能夠出現三種友元聲明:
(1)普通非模板類或函數的友元聲明,將友元關係授予明確指定的類或函數。
(2)類模板或函數模板的友元聲明,授予對友元全部實例的訪問權。
(3)只授予對類模板或函數模板的特定實例的訪問權的友元聲明。htm

要注意的是,友元函數並不是成員函數,是改變了它對類成員的訪問權限。對象

(1)沒有什麼好說的,如:blog

1 template<class T>
2 
3 class A{
4 
5    friend void fun();
6 
7 //...
8 
9 };

 

此例中fun可訪問A任意類實例中的私有和保護成員get

(2)

 1 template<class T>
 2 
 3 class A{
 4 
 5   template<class T>
 6 
 7    friend void fun(T u);
 8 
 9 //...
10 
11 };

 

這時友元使用與類不一樣的模板形參,T能夠是任意合法標誌符,友元函數能夠訪問A類的任何類實例的數據,即不論A的形參是int,double或其餘均可以。

(3)

1 template<class T>
2 
3 class A{
4 
5    friend void fun<T>(T u);
6 
7 //...
8 
9 };

 

此時fun只有訪問類中特定實例的數據。換句話說,此時具備相同模板實參的fun函數與A類纔是友元關係。即假如調用fun時其模板實參爲int,則它只具備A<int>的訪問權限。固然friend void fun<T>(T u);中<>中的T能夠是任意類型,好比int,double等

回到原問題,按(3)可改成:

template <class T> class List{
    friend std::ostream& operator << <T>(std::ostream& os,const List<T>& slist);
    //……
};

 

按(2)可改成:

1 template <class T> class List{
2 
3     template <class T>
4     friend std::ostream& operator << (std::ostream& os,const List<T>& slist);
5     //……
6 };

 

在這裏其實二者實現的最終效果同樣的,由於調用輸出運算符時須要訪問的類實例的對象是它自己,因此形參T在第一種改法中必定匹配。

相關文章
相關標籤/搜索