14.4.9模板类和友元

1.模板类的非模板友元函数

在模板类中将一个常规函数声明为友元:

template<class T>
class HasFriend
{
	public:
		friend void counts();
   ....
}

在模板类中声明一个带有模板类参数的友元:

template<class T>
class HasFriend
{
	public:
		friend void report(HasFriedn<T>& );
	....
}

下面看实际例子代码:

//
#include "pch.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<typename T>
int HasFriend<T>::ct = 0;

void counts()
{
	cout << "int 数量" << HasFriend<int>::ct << ";";
	cout << "double数量:" << HasFriend<double>::ct << endl;
}

void reports(HasFriend<int>& hf)
{
	cout << "HasFriend<int>:" << hf.item << endl;
}
void reports(HasFriend<double>& hf)
{
	cout << "HasFriend<double>:" << hf.item << endl;
}
int main()
{
    cout << "没有对象被声明:";
	counts();
	HasFriend<int> hfi1 (10);

	cout << "hfi1 被声明后: ";
	counts();
	HasFriend<int> hfi2(20);
	cout << "hfi2 被声明后: ";
	counts();
	HasFriend<double> hfdb(10.5);
	cout << "hfdb 被声明后: ";
	counts();
	reports(hfi1);
	reports(hfi2);
	reports(hfdb);
	return 0;
}

输出结果:
没有对象被声明:int 数量0;double数量:0
hfi1 被声明后: int 数量1;double数量:0
hfi2 被声明后: int 数量2;double数量:0
hfdb 被声明后: int 数量2;double数量:1
HasFriend:10
HasFriend:20
HasFriend:10.5


上面例子的静态变量ct,其实HasFriend和HasFriend各有一个不同的ct,他们相互独立,各自为自己的所属类服务,这和一般的类的静态变量不同。原因就不详细说了(原理我大概明白,但不是十分清晰,具体过程也不好班门弄斧)。

2.模板类的约束模板友元函数

要使类的每一个具体化都获得与友元匹配的具体化,会比非模板友元函数复杂一些。
需要分3步来完成:
第一步:在类定义前声明每个模板函数。

template<typename T> void counts();
template<typename T> void reports(T&);

第二步: 在函数中再次将模板声明为友元。这些语句根据类模板参数的类型声明具体化:

template<typename TT>
class HasFriendT
{
	.....
		friend void counts<TT>();
		friend void report<>(HasFriendT<TT>&);
};

声明中的<>指出这是模板具体化,report()<>可以为空,因为可以从函数参数推断出模板类型参数(HasFriend<TT>)。 当然 也可以这么用: report<HasFriendT<TT>>(HasFriend<TT> &);
但是counts()没有参数,所以就必须使用模板参数的语法(<TT>)来指明其具体化。还需要注意的是TTHasFriend类的参数类型。

下面是实例代码:

// ConsoleApplication2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
using std::cout;
using std::endl;

template<typename T> void counts();
template<typename T> void reports(T&);

template<typename TT>
class HasFriendT
{
	TT item;
	static int ct;
public:
	HasFriendT(const TT& i) :item(i) { ct++; };
	~HasFriendT() { ct--; };
	friend void counts<TT>();
	friend void reports<>(HasFriendT<TT>&);

};
template<typename T>
int HasFriendT<T>::ct = 0;
template<typename T>
void counts()
{
	cout << "模板大小:" << sizeof(HasFriendT<T>) << ";";
	cout << "模板数量:" << HasFriendT<T>::ct << endl;
}

template<typename T>
void reports(HasFriendT<T>& hf)
{
	cout << hf.item << endl;
}

int main()
{
	counts<int>();
	HasFriendT<int> hfi1(10);
	HasFriendT<int> hfi2(20);
	HasFriendT<double> hfdb(10.5);
	reports(hfi1);
	reports(hfi2);
	reports(hfdb);
	cout << "<int>的数量:\n";
	counts<int>();
	cout << "<double>的数量:\n";
	counts<double>();
	return 0;
}

输出结果:

模板大小:4;模板数量:0
10
20
10.5
<int>的数量:
模板大小:4;模板数量:2
<double>的数量:
模板大小:8;模板数量:1


如上所示,counts和counts报告的模板大小不同,这表明每种T类型都友自己的友元函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值