普通友元:FooBar的成员和fcn函数可以访问Bar类的任意实例的private成员和protected成员
模板友元类FooBar
#include <iostream> using namespace std; template <class Type> class Bar { friend class FooBar; Type pri; }; class FooBar { public: template<typename T> void foofcn(const Bar<T>& b); //{cout<<b.pri<<endl;}//内部定义 }; template<typename T> void FooBar::foofcn(const Bar<T>& b) {cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float> bf; FooBar fb; fb.foofcn(bi); fb.foofcn(bf); system("pause"); return 0; }
模板友元函数fcn
#include <iostream> using namespace std; template<class Type> class Bar { friend void fcn(const Bar& b) { cout<<b.pri<<endl;}//效果同下 //friend void fcn(const Bar<Type>& b) { cout<<b.pri<<endl;} Type pri; }; //在类外部定义不能用 const Bar& b形式 //void fcn(const Bar& b) //{ cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float>bf; fcn(bi); fcn(bf); system("pause"); }
一般模板友元关系:FooBar的任意实例都可以访问Bar的任意实例的私有成员。fcn函数相同
模板友元类FooBar
#include <iostream> using namespace std; template<class Type> class Bar { template<class T> friend class FooBar; Type pri; }; template<typename T> class FooBar { public: template<class U> void foofcn(const Bar<U>& b) { cout<<b.pri<<endl;} }; //在外面定义 /*template <class T> template<typename U> void FooBar<T>::foofcn(const Bar<U>& b) {cout<<b.pri<<endl;} */ int main(void) { Bar<int> bi; Bar<float> bf; FooBar<int> fbi; FooBar<float> fbf; fbi.foofcn(bi); fbi.foofcn(bf); fbf.foofcn(bi); fbf.foofcn(bf); system("pause"); return 0; }
模板友元函数fcn
#include <iostream> using namespace std; template<typename Type> class Bar { template<class T> friend void fcn(const Bar<T>& b) ; Type pri; }; template<typename T> void fcn(const Bar<T>& b) {cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float>bf; fcn(bi); fcn(bf); system("pause"); }
函数定义在模板内部会导致重复定义
#include <iostream> using namespace std; template<typename Type> class Bar { template<class T> friend void fcn(const Bar<T>& b) {cout<<b.pri<<endl;} Type pri; }; int main(void) { Bar<int> bi; //Bar<float>bf; fcn(bi); //fcn(bf); system("pause"); }
3.特定的模板友元关系:Bar实例只与有相同模板实参的FooBar版本是友元
3.1
模板友元类FooBar
#include <iostream> using namespace std; //需要前置声明 ,编译器将友元声明当作类的声明 template<class T> class FooBar; template<class Type> class Bar { friend class FooBar<Type>; Type pri; }; template<class T> class FooBar { public: void foofcn(const Bar<T>& b);// {cout<<b.pri<<endl;}//在内部定义 }; template<class T> void FooBar<T>:: foofcn(const Bar<T>& b) {cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float> bf; FooBar<int> fbi; FooBar<float> fbf; fbi.foofcn(bi); //fbi.foofcn(bf);//error //fbf.foofcn(bi);//error fbf.foofcn(bf); system("pause"); return 0; }
模板友元函数fcn
#include <iostream> using namespace std; template<class T> class Bar; template<class T> void fcn (const Bar<T>&);//需要前置声明 template<typename Type> class Bar { //friend void fcn<Type>(const Bar<Type>& b);//模板特化 friend void fcn<>(const Bar<Type>& b);//两种声明均可 Type pri; }; template<class T> void fcn (const Bar<T>& b) {cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float>bf; //fcn<float>(bi);//函数模板的类型可以和形参的模板类型不一致 fcn<int>(bi); fcn(bi); fcn(bf); fcn<float>(bf); //fcn<int>(bf); system("pause"); }
另一种写法,在模板类内部定义,调用fcn需要显示指定模板实参
#include <iostream> using namespace std; template<typename Type> class Bar { template<class T> friend void fcn(const Bar<Type>& b) {cout<<b.pri<<endl;} Type pri; }; int main(void) { Bar<int> bi; Bar<float>bf; fcn<float>(bi);//函数模板的类型可以和形参的模板类型不一致 fcn<int>(bi); //fcn(bf);//error//调用时要显示指定函数模板类型 fcn<int>(bf); system("pause"); }
3.2特定实例
模板友元类FooBar
#include <iostream> using namespace std; //需要前置声明 template<class T> class FooBar; template<class Type> class Bar { friend class FooBar<float>; Type pri; }; template<typename T> class FooBar { public: //foofcn(const Bar<T>& b)只能访问Bar的对应类型,不能访问所有类型 //void foofcn(const Bar<T>& b) {cout<<b.pri<<endl;} template<class U> void foofcn(const Bar<U>& b) {cout<<b.pri<<endl;} }; int main(void) { Bar<int> bi; Bar<float> bf; FooBar<int> fbi; FooBar<float> fbf; //fbi.foofcn(bi); //fbi.foofcn(bf);//error fbf.foofcn(bi);//如果定义为foofcn(const Bar<T>& b),则fbf没访问bi私有变量的权限 fbf.foofcn(bf); system("pause"); return 0; }
模板友元函数fcn
#include <iostream> using namespace std; template<class T> class Bar; template<class T> void fcn (const Bar<T>&);//需要前置声明 template<typename Type> class Bar { friend void fcn<float>(const Bar<float>& b); Type pri; }; template<class T> void fcn (const Bar<T>& b) {cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float>bf; //fcn<float>(bi);//函数模板的类型可以和形参的模板类型不一致 //fcn<int>(bi); //fcn(bi); fcn(bf);//只接受Bar<float>实参 fcn<float>(bf); //fcn<int>(bf); system("pause"); }
可以将fcn定义为非模板
#include <iostream> using namespace std; template<typename Type> class Bar { friend void fcn(const Bar<float>& b); Type pri; }; void fcn (const Bar<float>& b) {cout<<b.pri<<endl;} int main(void) { Bar<int> bi; Bar<float>bf; //fcn(bi); fcn(bf);//只接受Bar<float>实参 //fcn<float>(bf);//fcn不是模板类函数 system("pause"); }
非类型形参的模板友元
模板友元类FooBar
#include <iostream> using namespace std; template<int hi> class Bar { private: friend class FooBar; int pri; public: Bar():pri(hi) {} }; class FooBar { public: template<int hi> void foofcn(const Bar<hi>& b) { cout<<b.pri<<endl;} }; int main(void) { Bar<34> b; Bar<21> b1; FooBar fb; fb.foofcn(b); fb.foofcn(b1); system("pause"); return 0; }
模板友元函数fcn
#include <iostream> using namespace std; template<int hi> class Bar { private: int pri; public: Bar():pri(hi) {} friend void fcn (const Bar<hi>& b) {cout<<b.pri<<endl;} }; int main(void) { Bar<34> b; Bar<21> b1; fcn(b); fcn(b1); system("pause"); return 0; }
外部定义
#include <iostream> using namespace std; template<int hi> class Bar; template<int a> void fcn(const Bar<a>& ); template<int hi> class Bar { private: int pri; public: Bar():pri(hi) {} friend void fcn<> (const Bar<hi>& b);//定义在外部需要特化声明 }; template<int hi> void fcn(const Bar<hi>& b) {cout<<b.pri<<endl;} int main(void) { Bar<34> b; Bar<21> b1; fcn(b); fcn(b1); system("pause"); return 0; }
函数定义在类内部,每次实例化都会生成相应的版本,所以有时会导致重复定义的错误,但有些友元只能定义在模板的内部