• 将模板声明为友元


    将模板声明为友元

    1.1在类模板内部声明友元的函数模板

    #include 
    using namespace std;
    
    template<typename T>class A{
        T num;
    public:
        A(){
            num=T(5.5);
        }
        template<typename T> //声明为友元时也要加上template
        friend void show(const A<T>&a);
    };
    //函数模板
    template<typename T> void show(const A<T>&a){
        cout<<a.num<<endl;
    }
    
    int main(){
        A<int> a;
        show<int>(a);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1.2在类模板内部对显示模板参数的函数模板进行友元申明

    这种方法需要前置申明函数模板,考察如下程序。

    #include 
    using namespace std;
    template<typename T>class A; //这里是为了下一句用到A时,声明类A,同时说明其为模板类
    template<typename T>void show(const A<T>&a);//这里是对友元的提前声明为模板,说明T的含义
    
    template<typename T>class A{
        T num;
    public:
        A(){
            num=T(5.5);
        }
        friend void show<T>(const A<T>&a);//如果这里没有用template提前说明该友元为模板,则需要提前声明
    };
    
    template<typename T> void show(const A<T>&a){
        cout<<a.num<<endl;
    }
    
    int main(){
        A<int> a;
        show<int>(a);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    1.3在模板类内部直接声明并定义友元函数

    这种情况只能在模板类内部一起把函数的定义写出来,不能在外部实现,因为外部需要类型参数,而需要类型参数就是模板了。其实这种情况相当于一般的模板类的成员函数,也相当于一个函数模板。考察如下代码。

    #include 
    using namespace std;
    
    template<typename T>class A{
        T num;
    public:
        A(){
            num=T(5.5);
        }
        friend void show(const A<T>&a){//这个并没有用template说明,因为他直接定义在模板类内部,声明和实现在模板类内部
            cout<<a.num<<endl;
        }
    };
    
    int main(){
        A<int> a;
        show(a);
        getchar();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    程序正常编译运行并输出5。当然,将友元函数的定义改为:

    template<typename T> void show(const A<T>&a){//相当于函数模板
        cout<<a.num<<endl;
    }
    
    • 1
    • 2
    • 3

    也是完全可以的,如果将函数模板放在类模板外定义的话,和第一种方式相同。由于无论是江友元函数申明为一个使用了模板类的普通函数,还是一个函数模板,由于将友元函数直接定义在类模板体内,所以不会出现申明和定义见的不一致型。

    2.把类模板声明为类模板的友元

    把类模板声明为类模板的友元可以有两种方式。

    2.1在类模板内部对模板类进行友元申明

    这里要注意是对实例化后的模板类将其申明为类模板的友元,而不是类模板。因此实例化类模板时,类模板需要前置申明。考察如下程序。

    #include 
    using namespace std;
    
    template<typename T>class B; //类模板前置申明
    
    template<typename T>class A{
        T num;
    public:
        A(){
            num=T(5.5);
        }
        friend class B<T>;
    };
    
    template<typename T>class B{
    public:
        static void show(const A<T>& a){
            cout<<"a.num:"<<a.num<<endl;    
        }
    };
    
    int main(){
        A<int> a;
        B<int>::show(a);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.2在类模板内部对类模板进行友元申明

    这里要注意是直接将类模板申明为类模板的友元,而不是实例化后的模板咧,要与上面区别对待。这里就不需要将类模板B提前申明了,在类模板A中将B申明为:

    template< class T>friend class B;
    
    • 1

    同样可以将类模板B申明为类模板A的友元。

    不过,这两种方式在概念上还是有一些差异。第一种方式,类模板B的实例化依赖于类模板A的参数T。也就是说,对于一个特定的模板类A< t>来说,只有一个B的实例B< t>是它的友元类。而在第二中方式中,对于一个特定的类模板A< t>来说,B的任何实例B< u>都是它的友元类。

  • 相关阅读:
    JS高级(数据类型,数据_变量_内存)
    5.2 加载矢量图层(delimitedtext,spatialite,wfs,memory)
    vulnhub靶场之ADROIT: 1.0.1
    小米K8s运维-云原生方向(面经分享)
    uniapp AES加密解密
    GitHub-Issue 正确的提问方式
    基于SSM的高速公路的智能交通管理系统
    [附源码]Java计算机毕业设计SSM防疫卫生资讯推荐系统
    Scala的字符串插值
    Kubernetes 进阶训练营 存储
  • 原文地址:https://blog.csdn.net/qq_55125921/article/details/126076922