懒得抄了,直接截图,后面对模板类友元函数是单个类具体化的友元,还有模板类所有具体化的友元进行自己理解的总结。
总结:
1.模板类的非模版友元函数
友元函数与 T无关时,友元和类的实例化是一对多的关系。即这个友元函数是所有类实例化的友元,可以访问所有类里面的成员对象。
友元函数与 T有关时,比如包含T的参数等,指定友元的具体化只是对应具体化类的友元,即一对一的关系,指定具体化友元指定访问指定具体化类的成员对象。
2.模板类的约束模板友元函数
此种友元函数都要受到模板类类型参数T的影响,即指定友元的具体化只是对应具体化类的友元,是一对一的关系。
3.模板类的非约束模板友元函数
此种此种友元函数不受模板类类型参数T的影响,友元和类的实例化是一对多的关系。
判断友元和类的实例化是一对一还是一对多关系,最简单的方式是将模板类具体化几不同的版本:
如将14.22代码具体化<int>和<double>两个版本
源代码
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>&);
};
<int>版本(即将T替换为int)
class HasFriend
{
private:
int item;
static int ct;
public:
HasFriend(const int&i) :item(i) { ct++; }
~HasFriend() { ct--; }
friend void counts();
friend void reports(HasFriend<int>&);
};
counts()是HasFriend<int>友元,reports(HasFriend<int>&)也是HasFriend<int>的友元
<double>版本(即将T替换为double)
class HasFriend
{
private:
double item;
static int ct;
public:
HasFriend(const double&i) :item(i) { ct++; }
~HasFriend() { ct--; }
friend void counts();
friend void reports(HasFriend<double>&);
};
对比发现,counts()是既是HasFriend<int>的友元,也是HasFriend<double>友元,counts()和模板类具体化的友元关系是一对多的关系。
而reports(HasFriend<int>&)只是HasFriend<int>的友元,reports(HasFriend<double>&)也只是HasFriend<double>的友元,是一对一的关系。
既如果友元函数的具体化受到模板类的类型参数T的影响,则模板中的友元函数和类具体化的友元关系是一对多的关系,否则只是一对一的关系。