友元类
- 让某个类B称为另外一个类A的友元类,这样的话,类B就可以在其成员函数中访问类A的所有成员不管这些成员在类A中是用什么(public,protected,private)来修饰的。
- 如果现在类A和类B都变成了类模板,那么能否让类模板B成为类模板A的友元类模板呢?
- 让类模板的某个实例(具体的类)成为友元类
template <typename U> class B; -- 类模板B的声明 template <typename T> class A { friend class B<long>; -- 不需要任何public,private等修饰符。 private: int data; }; template <typename U> class B { public: void callBAF() { A<int> atmpobj; atmpobj.data = 5; cout << atmpobj.data << endl; } };
- 调用:
B<long> bobj; bobj.callBAF(); // 5
- 让类模板B特定的实例成为了类模板A的友元类。
- 让类模板成为友元类模板
template <typename T> class A { template<typename> friend class B; private: int data; }; template <typename U> class B { public: void callBAF() { A<int> atmpobj; atmpobj.data = 5; cout << atmpobj.data << endl; } };
- 调用:
B<long> bobj1; B<int> bobj2; bobj1.callBAF(); //5 bobj2.callBAF(); //5
- 让类型模板参数成为友元类
- C++11新标准中引入:如果传递进来的 类型模板参数 是一个类类型,则这个类类型可以成为当前类模板的友元类。
template <typename T> class A2 { friend T; private: int data; }; class CF { public: void callCFAF() { A2<CF> aobj1; -- 让CF类成为了A2 aobj1.data = 12; cout << aobj1.data << endl; } };
- 调用:
CF mycfobj; mycfobj.callCFAF();
- 输出:
12
- 代码行A2<CF> aobj1; 的效果是让CF类成为了A2<CF>类的友元类;
- 于是,在CF类的成员函数中(不是在其他域,如主函数中),可以直接访问aobj1这个A2<CF>类对象的data私有成员变量
- 如在main函数中直接访问A私有成员,编译报错
A2<_nmsp2::CF> aobj1; aobj1.data = 12;
- 如果传递给类模板A2的类型模板参数不是一个类类型,那么代码行friend T;就会被忽略。
template <typename T> class A2 { friend T; private: int data; }; class CF { public: void callCFAF() { -- 因为CF类并不是A2<int>的友元类,自然不能在这里访问aobj2这个A2<int>类对象的data私有成员变量。 A2<int> aobj2; aobj2.data = 15; cout << aobj2.data << endl; } };
- 调用报错:
CF mycfobj; mycfobj.callCFAF();
- 增加 friend class CF;则将整个CF类作为友元类
template <typename T> class A2 { friend T; friend class CF; private: int data; }; class CF { public: void callCFAF() { A2<CF> aobj1; //让CF类成为了A2<CF> aobj1.data = 12; cout << aobj1.data << endl; A2<int> aobj2; aobj2.data = 15; cout << aobj2.data << endl; } };
- 调用:
CF mycfobj; mycfobj.callCFAF();
- 输出:
12 15