关于类模板的友元函数

转载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在第一种改法中必定匹配。

相关文章
相关标签/搜索