C++模板类和友元

12.11 C++模板类和友元

12.11.1 非模板的友元函数

12.11.1.1 定义

friend void report(HasFriend &); // possible?

这是不可以的,因为形参没有指定类型,应该写为 HasFriend<特定类型(模板参数名或特定数据类型)> & 模板类中的static数据:要求每种模板的实例化都有自己的static成员(每种类型一个)

12.11.1.2 举例

HasFriend.h

#pragma once
#ifndef HASFRIEND_H_
#define HASFRIEND_H_
#include <iostream>
using std::cout;
using std::endl;
template <typename T>
class HasFriend
{
private:
    T item;
    static int ct;
public:
    HasFriend(const T& i) : item(i) { ct++; }
    ~HasFriend() { ct--; }
    friend void counts();
    friend void reports(HasFriend<T>&); // template parameter
};
// each specialization has its own static data member
template <typename T>
int HasFriend<T>::ct = 0;//这个就是对于每种类型的初始化
// non-template friend to all HasFriend<T> classes
void counts()
{
    cout << "int count: " << HasFriend<int>::ct << "; ";
    cout << "double count: " << HasFriend<double>::ct << endl;
}
// non-template friend to the HasFriend<int> 这两个是重载,类型分别是int和double
void reports(HasFriend<int>& hf)
{
    cout << "HasFriend<int>: " << hf.item << endl;
}
// non-template friend to the HasFriend<double> class
void reports(HasFriend<double>& hf)
{
    cout << "HasFriend<double>: " << hf.item << endl;
}
​
#endif

12.11.2 绑定模板友元函数

12.11.2.1 定义

定义绑定模板友元函数的三个步骤:

  • 1.在模板类定义之前声明模板函数

  • 2.将模板函数声明为模板类的友元函数

  • 3.为友元函数提供定义

执行时以友元函数的模板为准,友元函数给啥类型,类模板就是啥类型

12.11.2.2 举例

HasFriendT.h

#pragma once
#include <iostream>
using std::cout;
using std::endl;
// template prototypes
template <typename T> void counts();
template <typename T> void report(T&);
// template class
template <typename TT>
class HasFriendT
{
private:
    TT item;
    static int ct;
public:
    HasFriendT(const TT& i) : item(i) { ct++; }
    ~HasFriendT() { ct--; }
    friend void counts<TT>();
    friend void report<>(HasFriendT<TT>&);
};
template <typename T>
int HasFriendT<T>::ct = 0;
// template friend functions definitions
template <typename T>
void counts()
{
    cout << "template size: " << sizeof(HasFriendT<T>) << "; ";
    cout << "template counts(): " << HasFriendT<T>::ct << endl;
}
template <typename T>
void report(T& hf)
{
    cout << hf.item << endl;
}

12.11.3 非绑定模板友元函数

12.11.3.1 定义

友元模板函数的参数和类模板函数的参数不一样。 感觉还是友元函数模板为主导,然后友元函数是啥类型,就决定了使用的类模板类型。

12.11.3.2 举例

manyfrnd.h

#pragma once
#include <iostream>
using std::cout;
using std::endl;
template <typename T>
class ManyFriend
{
private:
    T item;
public:
    ManyFriend(const T& i) : item(i) {}
    template <typename C, typename D> friend void show2(C&, D&);
};
template <typename C, typename D> void show2(C& c, D& d)
{
    cout << c.item << ", " << d.item << endl;
}

12.11.4 代码

main.h

#pragma once
#ifndef MAIN_H_
#define MAIN_H_
#include <iostream> //输入输出 
#include "HasFriend.h" //Template_Classes_and_Friends
#include "HasFriendT.h" //Template_Classes_and_Friends
#include "manyfrnd.h" //Template_Classes_and_Friends
using namespace std;
void Template_Classes_and_Friends(void)
{
    std::cout << "\nTemplate_Classes_and_Friends Hello************************************************\n";
        cout << "Non-template friends*********************************************" << std::endl;
        cout << "No objects declared: ";
        counts();
        HasFriend<int> hfi1(10);
        cout << "After hfi1 declared: ";
        counts();
        HasFriend<int> hfi2(20);
        cout << "After hfi2 declared: ";
        counts();
        HasFriend<double> hfdb(10.5);
        cout << "After hfdb declared: ";
        counts();
        reports(hfi1);
        reports(hfi2);
        reports(hfdb);
        cout << "Bound Template Friend Functions***************************************" << std::endl;
        counts<int>();
        HasFriendT<int> hfi3(10);
        HasFriendT<int> hfi4(20);
        HasFriendT<double> hfdb1(10.5);
        report(hfi3); // generate report(HasFriendT<int> &)
        report(hfi4); // generate report(HasFriendT<int> &)
        report(hfdb1); // generate report(HasFriendT<double> &)
        cout << "counts<int>() output:\n";
        counts<int>();
        cout << "counts<double>() output:\n";
        counts<double>();
        cout << "Unbound Template Friend Functions*************************************" << std::endl;
        ManyFriend<int> hfi5(10);
        ManyFriend<int> hfi6(20);
        ManyFriend<double> hfdb2(10.5);
        cout << "hfi5, hfi6: ";
        show2(hfi5, hfi6);
        cout << "hfdb2, hfi6: ";
        show2(hfdb2, hfi6);
        std::cout << "\nTemplate_Classes_and_Friends Bye************************************************\n";
}
#endif

main.cpp

/*
Project name :          _12template
Last modified Date:     2022年5月6日11点33分
Last Version:           V1.0
Descriptions:           模板类和友元
*/
#include "main.h"
​
int main()
{
    cout << "模板类和友元******************************************************************" << endl;
    Template_Classes_and_Friends();
​
    return 0;
}

12.11.5 运行结果

模板类和友元******************************************************************
Template_Classes_and_Friends Hello************************************************
Non-template friends*********************************************
No objects declared: int count: 0; double count: 0
After hfi1 declared: int count: 1; double count: 0
After hfi2 declared: int count: 2; double count: 0
After hfdb declared: int count: 2; double count: 1
HasFriend<int>: 10
HasFriend<int>: 20
HasFriend<double>: 10.5
Bound Template Friend Functions***************************************
template size: 4; template counts(): 0
10
20
10.5
counts<int>() output:
template size: 4; template counts(): 2
counts<double>() output:
template size: 8; template counts(): 1
Unbound Template Friend Functions*************************************
hfi5, hfi6: 10, 20
hfdb2, hfi6: 10.5, 20
​
Template_Classes_and_Friends Bye************************************************
​
D:\Prj\_C++Self\_12template\Debug\_12template.exe (进程 328)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jasmine-Lily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值