函数、类、类的成员函数作为类模板的友元
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void Func1(){} class A{}; class B { public: void Func(){} }; template<class T> class Tmpl { friend void Func1(); friend class A; friend void B::Func(); };
int main() { Tmpl<int> i; Tmpl<double> f; return 0; }
|
类模板实例化时,除了类型参数被替换外,其他所有内容都原样保留,因此任何从
Tmpl 实例化得到的类都包含上面三条友元声明,因而也都会把 Func1、类A 和
B::Func 当作友元。
函数模板作为类模板的友元
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include<iostream> #include<string> using namespace std; template<class T1, class T2> class Pair { private: T1 key; T2 value; public: Pair(T1 k, T2 v): key(k), value(v) {}; bool operator<(const Pair<T1, T2> & p) const; template<class T3, class T4> friend ostream & operator<<(ostream & o, const Pair<T3, T4> &p); }; template<class T1, class T2> bool Pair<T1, T2>::operator<(const Pair<T1, T2> &p) const { return key < p.key; } template<class T1, class T2> ostream & operator<<(ostream &o, const Pair<T1, T2> &p) { o << "(" << p.key << "," << p.value << ")"; return o; } int main() { Pair<string, int> student("Tom", 29); Pair<int, double> obj(12, 3.14); cout << student << " " << obj; return 0; }
|
程序的输出结果是:
第 13、14 行将函数模板 operator<< 声明为类模板 Pair
的友元。
编译本程序时,编译器自动生成了两个 operator<<
函数,它们的原型分别是:
1 2
| ostream& operator<<(ostream &o, const Pair<string, int> &p); ostream& operator<<(ostream &o, const Pair<int, double> &p);
|
前者是 Pair<string, int> 类的友元,但不是 Pair<int,
double> 类的友元。后者相反。
函数模板作为类的友元
实际上,类也可以将函数模板声明为友元。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include<iostream> using namespace std; class A { int v; public: A(int n): v(n) {} template<class T> friend void Print(const T & p); }; template<class T> void Print(const T &p) { cout << p.v; } int main() { A a(4); Print(a); return 0; }
|
程序的输出结果是:
编译器编译到第 19 行 Print(a);
时,就从 Print
模板实例化出一个 Print 函数,原型如下:
1
| void Print(const A & p);
|
这个函数本来不能访问 p 的私有成员。但是编译器发现,如果将类 A
的友元声明中的 T 换成 A,就能起到将该 Print
函数声明为友元的作用,因此编译器就认为该 Print 函数是类 A 的友元。
类模板作为类模板的友元
一个类模板还可以将另一个类模板声明为友元。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include<iostream> using namespace std; template<class T> class A { public: void Func(const T & p) { cout << p.v; } }; template<class T> class B { private: T v; public: B(T n): v(n) {} template<class T2> friend class A; }; int main() { B<int> b(5); A< B<int> > a; a.Func(b); return 0; }
|
程序输出结果:
在本程序中,A< B > 类称为 B 类的友元。