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>
)来指明其具体化。还需要注意的是TT
是HasFriend
类的参数类型。
下面是实例代码:
// 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类型都友自己的友元函数