模板的友元声明
在类模板中可以出现三种友元声明,每一种都声明了与一个或多个实体的友元关系
1. 普通非模板或函数的友元声明,将友元关系授予明确指定的类或函数。
2. 类模板或函数模板的友元声明,授予对友元所有实例的访问权。
3. 只授予对类模板和函数模板的特定实例的访问权的友元声明。
普通友元声明
template <class Type> class Bar
{
friend class FooBar;
friend void fcn();
};
FooBar的成员和fcn函数可以访问Bar类的任意实例的private成员和protected成员
一般模板友元关系
template <class Type> class Bar
{
template <class T> friend class Fool;
template <class T> friend void temp_fcn(const T&);
};
Fool 的任意实例都可以访问Bar的任意实例的私有元素,类似的,tmp_fcn的任意实例也可以访问Bar的任意实例。
这个友元声明在Bar与其友元Fool和tmp_fcn的每个实例之间建立了一对多的映射,对Bar的每个实例而言,Fool和tmp_fcn的所有的实例都是友元。
特定的模板友元关系
template <class T> class Foo2;
template <class T> void temp_fcn(const T&);
template <class Type> class Bar
{
friend class Foo2<char *>;
friend void temp_fcn<char *>(char * const &);
};
只有形参类型为char *的Foo2实例是Bar类的友元,形参为char*类型的Foo2和temp_fcn的特定实例可以访问Bar的每个实例
*下面的声明更为常见
template <class T> class Foo3;
template <class T> void temp_fcn(const T&);
template <class Type> class Bar
{
friend class Foo3<Type>;
friend class temp_fcn<Type>(const Type&);
......
};
只有与给定Bar实例有相同模板实参的那些Foo3或temp_fcn版本是友元,上面的声明建立了Bar和Foo3的一一映射关系
4. 声明依赖性
当授予给定模板的所有实例的访问权的时候,在作用域中不需要存在该类模板或函数模板的声明
想要限制对特定实例化的友元关系时,必须在可以用于友元声明之前声明类或函数
template<class T> class A;
template<class T> class B{
public:
friend class A<T>; //第三种类型,一一对应
friend class C; //授予c类 B类任意实例的访问权
template <class S> friend class D;// D的任意实例都有权访问B的所有实例
friend class E<T>; //error,应和A一样,事先声明
friend class F<int>; // error,应事先声明(在类B定义之前加上 tempalte <class T> class F; 即可);
};
阅读(244) | 评论(0) | 转发(0) |