类模板中的友元函数的定义

类模板和友元简介:

当一个类被包含一个友元声明的时候,类和友元是否是模板是相互无关的

如果一个类模板包含一个非模板友元,则友元被授权可以访问所有模板实例;

如果友元自身是模板,类可以授权给所有友元模板实例,也可以之授权给特定实例。

一、友元和类模板的一对一关系:

类模板另一个(类或函数)模板间友好关系的最常见的形式是:

建立对应实例及其友元间的友好关系。
例如:

//前置声明,在Blob中声明友元所需要的。
template<typename> class BlobPtr;
template<typename> class Blob;//运算符==中的参数需要的
//之后进行模板函数声明:
template<typename T>
bool operator==(const Blob<T>&, const Blob<T>&);//实参类型必须一致

template<typename T> class Blob{
     
	//每个Blob实例将访问权限授予用相同类型实例化的BlobPtr和相等运算符
	friend class BlobPtr;
	friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
	//operator==是针对某个实例化类型的,所以要也加一个
	//其他成员定义略。
}

首先将Blob、BlobPtr和operation== 声明为模板。这些声明是operation==函数的参数声明以及Blob中的友元声明所需要的。如果要把

友元的声明用Blob的模板形参作为他们自己的模板实参,因此,友元关系被限定在用相同类型实例化的Blob和BlobPtr

实例化一下:

Blob<char> ca;  //BlobPtr和operator==都是ca的友元
Blob<int> ia;	//BlobPtr和operator==都是ia的友元

因此BlobPtr的成员可以访问ca(或任何其他Blob对象)的非public部分,但ca对ia(或其他任何Blob对象)或Blob的任何其他实例都没有特殊的访问权限。

二、通用和特定的模板的友好关系:

一个类可以将另一个类模板的每个实例都声明为自己的友元(即通用模板),或者限定特定的实例为友元(即特定模板):

//前置声明,在将模板的一个特定实例声明为友元时要用到
template<typename T> class Pal;

class C{
     //C为一个普通的非模板类
	friend class Pal<C>;//pal本身是类模板,用C实例化后,pal的类型是C,
	//C类型的pal又成为了非模板类C的友元
	
	//Pal2的所有实例都是C的友元;这种情况无须前置声明
	temlate<typename T> friend class Pal2;
};

比较来看,前者是限定了只有实例化为C类的Pal才是非模板类C的友元;

而对于Pal2来说,任何类型,包括int,double,string,C等等都是非模板类C的友元。

因此两者模板的定义方式也不一样,前者需要先在类外定义模板,因为类内就要限定实例化了,所以要提前准备好。

而后者则不然,为了让所有实例都成为友元,友元声明中必须使用域类模板本身不同的模板参数。

三、令模板自己的参数类型成为友元:

在新标准中,我们可以将模板类型参数声明为友元:

template<typename T>class B{
     
	friend T;	//将访问权限授予用来实例化Bar的类型
	//......
};

此处我们将用来实例化Bar的类型声明为友元。因此,对于某个类型名F,F将成为B的友元,S成为B的友元,以此类推。

小结:

主要阐述了友元函数在类内的声明,其他模板类的友元和自身友元的定义

你可能感兴趣的:(基础知识,c++)