C++ 模板类与友元

模板类的友元函数有三类:
1)非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数。
2)约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
3)非约束模板友元:模板类实例化时,如果实例化了n个类,也会实例化n个友元函数,每个实例化的类都拥有n个友元函数。

1)非模板友元示例:

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

template<class T1, class T2>
class AA    
{
    T1 m_x;
    T2 m_y;
public:
    AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
    // 非模板友元:友元函数不是模板函数,而是利用模板类参数生成的函数,只能在类内实现。
    friend void show(const AA<T1, T2>& a)
    {
        cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
    }
   /* friend void show(const AA<int, string>& a);
    friend void show(const AA<char, string>& a);*/
};

//void show(const AA<int, string>& a)
//{
//    cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}
//
//void show(const AA<char, string>& a)
//{
//    cout << "x = " << a.m_x << ", y = " << a.m_y << endl;
//}

int main()
{
    AA<int, string> a(88, "我是一只傻傻鸟。");
    show(a);

    AA<char, string> b(88, "我是一只傻傻鸟。");
    show(b);
}

2)约束模板友元示例:

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

// 约束模板友元:模板类实例化时,每个实例化的类对应一个友元函数。
template <typename T>
void show(T& a);                                                 // 第一步:在模板类的定义前面,声明友元函数模板。

template<class T1, class T2>
class AA    // 模板类AA。
{
    friend void show<>(AA<T1, T2>& a);          // 第二步:在模板类中,再次声明友元函数模板。
    T1 m_x;
    T2 m_y;

public:

    AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};

template<class T1, class T2>
class BB    // 模板类BB。
{
    friend void show<>(BB<T1, T2>& a);          // 第二步:在模板类中,再次声明友元函数模板。
    T1 m_x;
    T2 m_y;

public:

    BB(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};

template <typename T>                                 // 第三步:友元函数模板的定义。
void show(T& a)
{
    cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}

template <>                                                    // 第三步:具体化版本。
void show(AA<int, string>& a)
{
    cout << "具体AA<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}

template <>                                                    // 第三步:具体化版本。
void show(BB<int, string>& a)
{
    cout << "具体BB<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}

int main()
{
    AA<int, string> a1(88, "我是一只傻傻鸟。");
    show(a1);         // 将使用具体化的版本。

    AA<char, string> a2(88, "我是一只傻傻鸟。");
    show(a2);        // 将使用通用的版本。

    BB<int, string> b1(88, "我是一只傻傻鸟。");
    show(b1);         // 将使用具体化的版本。

    BB<char, string> b2(88, "我是一只傻傻鸟。");
    show(b2);        // 将使用通用的版本。
}

3)非约束模板友元

#include <iostream>         // 包含头文件。
using namespace std;        // 指定缺省的命名空间。

// 非类模板约束的友元函数,实例化后,每个函数都是每个每个类的友元。
template<class T1, class T2>
class AA    
{
    template <typename T> friend void show(T& a);     // 把函数模板设置为友元。
    T1 m_x;
    T2 m_y;
public:
    AA(const T1 x, const T2 y) : m_x(x), m_y(y) { }
};

template <typename T> void show(T& a)                     // 通用的函数模板。
{
    cout << "通用:x = " << a.m_x << ", y = " << a.m_y << endl;
}

template <>void show(AA<int, string>& a)                 // 函数模板的具体版本。
{
    cout << "具体<int, string>:x = " << a.m_x << ", y = " << a.m_y << endl;
}

int main()
{
    AA<int, string> a(88, "我是一只傻傻鸟。");
    show(a);         // 将使用具体化的版本。

    AA<char, string> b(88, "我是一只傻傻鸟。");
    show(b);        // 将使用通用的版本。
}


推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家:
零声白金学习卡(含基础架构/高性能存储/golang云原生/音视频/Linux内核)
https://xxetb.xet.tech/s/3Zqhgt

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值