类模板的友元

详见http://www.cnblogs.com/assemble8086/archive/2011/10/02/2198308.html

 

类模板的友元有三种声明:

 

1)非模板类的友元类或友元函数

1 template <typename T>
2 class Rect{
3 public:
4    friend void create(); 
5 };

 

 create函数成为所有Rect类实例化的友元,它可以访问全局对象;可以使用全局指针访问非全局对象;可以创建自己的对象;可以访问独立对象的模板类的静态数据成员。

1 template <typename T>
2 class Rect{
3 public:
4    friend void create(Rect<T>&); 
5 };

 

 这种声明使得create函数传入了Rect类的实例,create(Rect<T>&)将成为Rect<T>类的友元。

 

2)绑定的友元类模板或友元函数

 1 template <typename T>
 2 class Rect;
 3 template <typename T>
 4 ostream& operator<<(ostream&,const Rect<T>&);
 5 
 6 
 7 template <typename T>
 8 class Rect{
 9 public:
10    friend ostream& operator<< <T>(ostream&,const Rect<T>&);
11 };

 

 该声明表示类模板的实例和它的友元之间是一种一对一的映射关系。

 将友元模板函数声明在类模板中,定义在类模板之外。当模板函数被声明为类模板的友元时,在函数名之后必须紧跟模板实参表,用来代表该友元声明指向函数模板的实例。否则友元函数会被解释为一个非模板函数,链接时无法解析。

 

3)非绑定的友元类模板或友元函数

 该声明表示类模板的实例和它的友元之间是一种一对多的映射关系。对于非约束友元,友元模板类型参数与模板类类型参数是不同的。

 1 template <typename T>
 2 class Rect{
 3 public:
 4       Rect(const T&i):item(i){}
 5       template <typename T2,typename T3>
 6       friend void show(T2&,T3&); 
 7 private:
 8       T item;
 9 }; 
10 
11 template <typename T2,typename T3>
12 void show(T2& rect1,T3& rect2)
13 {
14     cout << rect1.item << " , " << rect2.item << endl;
15 }   

 

 通过在类内部声明模板,可以创建非约束友元函数,即每个函数具体化都是每个类具体化的友元。

1 int main()
2 {
3     Rect<int> R1(10);
4     Rect<double> R2(7.5);
5     show(R1,R2);
6 }

 

show是所有Rect具体化的友元,并访问了Rect<int>对象的item成员和Rect<double>对象的item成员。

 

posted @ 2016-08-14 12:54  Fantasy's  阅读(1282)  评论(0编辑  收藏  举报