C++ 模板中定义友元
在類模板中可以出現三種友元聲明:
(1)普通非模板類或函數的友元聲明,將友元關系授予明確指定的類或函數。
(2)類模板或函數模板的友元聲明,授予對友元所有實例的訪問權。
(3)只授予對類模板或函數模板的特定實例的訪問權的友元聲明。
要注意的是,友元函數并非成員函數,是改變了它對類成員的訪問權限。
(1)沒有什么好說的,如:
template<class T>
class A{
friend void fun();
//...
};
此例中fun可訪問A任意類實例中的私有和保護成員
(2)
template<class T>
class A{
template<class T>
friend void fun(T u);
//...
};
這時友元使用與類不同的模板形參,T可以是任意合法標志符,友元函數可以訪問A類的任何類實例的數據,即不論A的形參是int,double或其他都可以。
(3)
template<class T>
class A{
friend void fun<T>(T u);
//...
};
此時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)可改為:
template <class T> class List{
template <class T>
friend std::ostream& operator << (std::ostream& os,const List<T>& slist);
//……
};
在這里其實兩者實現的最終效果一樣的,因為調用輸出運算符時需要訪問的類實例的對象是它本身,所以形參T在第一種改法中一定匹配。
對類建立友元函數很容易。但是遷移到模板上卻容易出現讓人摸不著頭腦的連接錯誤。
層次不夠,不做分析,單純介紹兩種為類模板定義友元函數的方法
1 封閉型
classMyClass
{
friend voidfunction( MyClass<T >&arg )
{
}
}; 要點:友元函數定義在模板體內。
2 開放型
template<typename T >
classMyClass
{
template<typename C >
friend voidfunction( MyClass<C >&arg );
};
template<typename C >
voidfunction( MyClass<C >&arg )
{
} 要點:模板體內要另建模板。
3 告訴編譯器聲明的設個是模板
#include <iostream>
usingnamespacestd;
template <typename T >
classA
{
friend ostream &operator<< < T >( ostream &, constA<T >&);
};
template <typename T >
ostream &operator<<( ostream &output, constA<T >&a )
{
output <<"重載成功"<<endl;
returnoutput;
}
intmain()
{
A<int>a;
cout <<a;
}要點:顯示地在重載的運算符或者函數后面加上模板聲明< T >,告訴編譯器友元函數是一個類型一致的模板。
(這個方法在VS2010沒通過)
建議:
如果希望使用函數與模板特化的類型相對應,則使用方法3(模板顯示聲明)
如果希望使用函數與模板特化的類型相獨立,則使用方法2(二重模板)
簡短的內聯函數使用方法1本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/squarereal/archive/2009/09/23/4579950.aspx
轉載于:https://blog.51cto.com/7209253/1201974
總結
以上是生活随笔為你收集整理的C++ 模板中定义友元的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【原创】自动更新程序2--更新程序的主窗
- 下一篇: springmvc国际化