zoukankan      html  css  js  c++  java
  • 关于类模板的友元函数

    转载

    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可编译,但无法链接:无法解析的外部符号……

    后来上网查改为

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

    就可以了。不知所以然,查了下《C++ Primer》才弄明白。

    在类模板中可以出现三种友元声明:
    (1)普通非模板类或函数的友元声明,将友元关系授予明确指定的类或函数。
    (2)类模板或函数模板的友元声明,授予对友元所有实例的访问权。
    (3)只授予对类模板或函数模板的特定实例的访问权的友元声明。

    要注意的是,友元函数并非成员函数,是改变了它对类成员的访问权限。

    (1)没有什么好说的,如:

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

    此例中fun可访问A任意类实例中的私有和保护成员

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

  • 相关阅读:
    关于字段长度的定义
    连续滚动效果的脚本
    JavaScript显示日期,跳动时间,星期
    [转载]SQL2000里的数据类型
    VSTSTF54000错误
    Delphi TreeView 现场保存与恢复
    易简协同平台与佛道修行
    CMD 反编译CHM文件
    专家与大师
    流程建模思考(草)
  • 原文地址:https://www.cnblogs.com/liangliangdetianxia/p/4495610.html
Copyright © 2011-2022 走看看