类模板中的友元声明

有三种友元声明可以出现在类模板中:

1、非模板友元类或友元函数。在下面的例子中,函数foo()、成员函数bar()以及foobar类都是类模板QueueItem的所有实例的友元。

class Foo
{
	void bar() ;
};

template<class T>
class QueueItem
{
	friend class foobar ;
	friend void foo() ;
	friend void Foo::bar() ; //注意这里
};


       上面的例子中,注意第三条,在QueueItem类把Foo类的一个成员声明为友元之前,Foo类必须已经被定义。且一个类成员只能由该类的定义引入。在Foo的定义可见之前,QueueItem不能引用Foo::bar()。

2、绑定的友元类模板或函数模板。下列例子中,在类模板QueueItem的实例和它的友元(也是模板实例)之间定义了一对一的映射。因为模板参数表中的参数是同一个,都是Type。对QueueItem的每一个类型的实例,foobar、foo()和Queue<Type>::bar()的单个相关的实例都是友元。如下所示:

template<class Type>
class foobar { ... };

template<class Type>
void foo(QueueItem<Type>) ;

template<class Type>
class Queue
{ 
	void bar () ;
	// ... 
};

template<class Type>
class QueueItem
{
	friend class foobar<Type> ;
	friend void foo<Type>(QueueItem<Type>) ;
	friend void Queue<Type>::bar() ;
    // .... 
};

       在一个模板可以被用在一个类模板的友元声明之前,它的声明或定义必须先被给出。在我们的例子中,在QueueItem类中的友元声明之前,必须先声明类模板foobar和Queue,以及函数模板foo()。

      foo()的友元声明的语法看起来或许令人吃惊:

friend void foo<Type>(QueueItem<Type>) ;


       函数名后面紧跟着显示的模板实参表:foo<Type>。这种语法可用来指定该友元声明所引用的是函数模板foo()的实例。如果省略了显示的模板实参,如下所示:

friend void foo(QueueItem<Type>) ;

       则友元声明会别解释为引用了一个非模板函数,且该函数的参数类型是类模板QueueItem的一个实例。模板函数和同名的非模板函数可以共存。虽然在QueueItem类的定义之前存在函数模板的声明,但是这不会强迫友元声明指向该模板。所以,我们必须为“引用函数模板实例的友元声明”指示显示的模板参数表。

3、非绑定的友元类模板或函数模板。在下面的例子中,在类模板QueueItem的实例和其友元之间定义了一对多的映射。因为模板参数表中的参数是不一样的。QueueItem的参数是Type,而其他的友元模板参数是T。对QueueItem的每一个类型的实例,foobar、foo()和Queue<T>::bar的所有实例都是友元。如下所示:

template<class Type>
class QueueItem
{
	template<class T> friend class foobar<T> ;
	template<class T> friend void foo(QueueItem<T>) ;
	template<class T> friend void Queue<T>::bar() ;
    // .... 
};




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值