C++类模板(模板类)与友元详解
发布时间:2020-12-16 07:41:29 所属栏目:百科 来源:网络整理
导读:下面我们分四种情况分别讨论。 1. 函数、类、类的成员函数作为类模板的友元 函数、类、类的成员函数都可以作为类模板的友元。程序示例如下: void Func1() { }class A { };class B{public: void Func() { }};template class Tclass Tmpl{ friend void Func1()
下面我们分四种情况分别讨论。
1. 函数、类、类的成员函数作为类模板的友元函数、类、类的成员函数都可以作为类模板的友元。程序示例如下: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; }类模板实例化时,除了类型参数被替换外,其他所有内容都原样保留,因此任何从 Tmp1 实例化得到的类都包含上面三条友元声明,因而也都会把 Func1、类 A 和 B::Func 当作友元。 2. 函数模板作为类模板的友元例题:在《C++类模板(模板类)》一节中我们定义了?Pair 模板,将<< 运算符重载为一个函数模板,并将该函数模板作为 Pair 模板的友元,这样,任何从 Pair 模板实例化得到的对象都能用<< 运算符通过 cout 输出。程序代码如下(函数模板作为类模板的友元): #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 Tl,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; }程序的输出结果是: (Torn,29) (12,3.14) 第 13、14 行将函数模板 operator<< 声明为类模板 Pair 的友元。在 Visual Studio 中,这两行也可以用下面的写法替代: friend ostream & operator<< <T1,T2>(ostream & o,T2> & p); 但在 Dev C ++ 中,替代后编译就无法通过了。编译本程序时,编译器自动生成了两个 operator << 函数,它们的原型分别是:
ostream & operator << (ostream & o,const Pair<string,int> & p); 3. 函数模板作为类的友元实际上,类也可以将函数模板声明为友元。程序示例如下:#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; }程序的输出结果是: 4 编译器编译到第 19 行 Print(a); 时,就从 Print 模板实例化出一个 Print 函数,原型如下:
void Print(const A & p); 这个函数本来不能访问 p 的私有成员。但是编译器发现,如果将类 A 的友元声明中的 T 换成 A,就能起到将该 Print 函数声明为友元的作用,因此编译器就认为该 Print 函数是类 A 的友元。思考题:类还可以将类模板或类模板的成员函数声明为友元。自行研究这两种情况该怎么写。 4. 类模板作为类模板的友元一个类模板还可以将另一个类模板声明为友元。程序示例如下:#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; //把类模板A声明为友元 }; int main() { B<int> b(5); A< B<int> > a; //用B<int>替换A模板中的 T a.Func(b); return 0; }程序的输出结果是: 5 在本程序中,A< B<int> > 类成为 B<int> 类的友元。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |