1. 当为一个类模板声明友元类模板或函数模板时,如果授予给定模板所有实例访问权,那么,在作用域中不需要存在该类模板或函数模板的声明,实际上,编辑器将友元声明也当做类或者函数的声明对待;
//template <typename Type> class Queue;//由于对类模板Queue的所有实例授予友元关系,所以不需要对类模板Queue进行事先声明,因为编译器将友元声明也当做声明
template <typename Type>
class QueueItem
{
public:
friend class Queue ; //对类模板Queue的所有实例授予友元访问权(比如:Queue<int> Queue<string>等),
//其它私有数据
private:
QueueItem(const Type &t):item(t), next(0) {}
Type item;
QueueItem *next;
};
2. 如果授予给定模板特定实例的友元访问权,必须在可以用于声明友元关系声明之前对该类模板或函数模板进行声明;
template <typename Type> class Queue; //告诉编译器Queue是一个类模板
//由于仅仅对类模板Queue的特定类型的实例授予友元关系,声明特定类型时须带模板形参类型名字,所以必须事先声明类Queue是一个类模板,因为只有类模板或者函数模板才可以带类型形参
template <typename Type>
class QueueItem
{
public:
friend class Queue<Type> ;//带有类型形参Type,如果缺少第一行的声明,会提示“Queue不是一个模板”
//仅仅对类模板Queue的特定实例授予友元访问权(比如:Queue<int>或者Queue<string>等)
//这里说的特定类型实例是指:QueueItem的int类型的实例即QueueItem<int>的protect和private成员仅仅可以被友元类模板Queue的int实例即Queue<int>的成员访问,而不能被其他类型访问如:Queue<string>不能访问QueueItem<int>,也就是特定类型实例之间是一对一的访问关系;
//其它私有数据
private:
QueueItem(const Type &t):item(t), next(0) {}
Type item;
QueueItem *next;
};