//第二十三模板 15模和友元 //模板类也可以声明为友元,模板类的友元共分三种情况 //1 非模板友元类或者友元函数 //2 通用模板类或者友元函数 //3 特定类型的模板友元类或者友元函数 //1非模板的友元类和友元函数 //我们可以将任何类或者函数声明为模板类的友元,这样由模板类生成的每个具体类都会正确处理友元类或者友元函数,就好像友元关系已经在具体化的类中声明了一样 /*#include <iostream> using namespace std; const int size=10; template<class T> class num { public: num(int Tsize=size); num(const num&r); ~num(){delete []pt; } num&operator=(const num&); T&operator[](int offset){ return pt[offset]; } const T&operator[](int offset)const { return pt[offset]; } int GetSize()const{ return numsize; } friend void print(num<T>);//友元 private: int numsize; T *pt; }; //定义友元 template<class T> void print(num<T> sw) { cout<<"friend函数执行"<<endl; //for(int i=0; i<sw.numsize; i++){ //cout<<"num["<<i<<"]: \t"<<sw.pt[i]<<endl; //} } //带一个参数的构造函数 template<class T> num<T>::num(int size):numsize(size) { cout<<"执行构造函数"<<endl; pt = new T[size]; for(int i=0; i<size; i++){ pt[i] = 0; } cout<<"numsize:"<<numsize<<endl; } //定义的复制构造函数 template<class T> num<T>::num(const num&r) { numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } //重载运算符= template<class T> num<T>&num<T>::operator=(const num&r) { if(this == &r){ return *this; delete []pt; numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } return *this; } int main() { num<int>one; for(int i=0; i<one.GetSize(); i++) { one[i] = i*2; cout<<one[i]<<endl; } print(one); //for(int i=0; i<one.GetSize(); i++){ //cout<<"num["<<i<<"]: \t"<<one.pt[i]<<endl; //cout<<one.pt[i]<<endl; //} return 0; }*/ //正确的方法 /* #include <iostream> using namespace std; const int size=10; template<class T> class num { public: num(int Tsize=size); num(const num&r); ~num(){delete []pt; } num&operator=(const num&); T&operator[](int offset){ return pt[offset]; } const T&operator[](int offset)const { return pt[offset]; } int GetSize()const{ return numsize; } friend void print(num<T>);//友元 private: int numsize; T *pt; }; void print(num<int>sw) { cout<<"friend函数执行"<<endl; for(int i=0; i<sw.numsize; i++){ cout<<"num["<<i<<"]: \t"<<sw.pt[i]<<endl; } } void print(num<double>sw) { cout<<"friend函数执行"<<endl; for(int i=0; i<sw.numsize; i++){ cout<<"num["<<i<<"]: \t"<<sw.pt[i]<<endl; } } //带一个参数的构造函数 template<class T> num<T>::num(int size):numsize(size) { cout<<"执行构造函数"<<endl; pt = new T[size]; for(int i=0; i<size; i++){ pt[i] = 0; } cout<<"numsize:"<<numsize<<endl; } //定义的复制构造函数 template<class T> num<T>::num(const num&r) { numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } //重载运算符= template<class T> num<T>&num<T>::operator=(const num&r) { if(this == &r){ return *this; delete []pt; numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } return *this; } int main() { num<int>one; num<double>two; for(int i=0; i<one.GetSize(); i++) { one[i] = i*2; two[i] = i*5; } print(one); print(two); return 0; }*/ //由于print()函数被声明为一个非模板友元函数,因此它并不是一个模板函数,而只是使用了模板的参数T,这样我们必须在定义函数时具体化模板参数T,该函数才被正确的创建, //2 通用模板友元类的友元函数 //友元函数被声明为一个模板函数,因此我们不用显示式具体化友元函数的定义部分 //class num{ //public: // template<class T1> // friend void print(num<t1>); //} //template<class T1>将print()友元函数说明为一个模板函数,这样print()函数便可适用于任何类型,注意,通用模板友元函数与模板类的模板参数是不同的,模板类的模板参数是T,而模板友元函数的模板能数是T1 /* #include <iostream> using namespace std; const int size=10; template<class T> class num { public: num(int Tsize=size); num(const num&r); ~num(){delete []pt; } num&operator=(const num&); T&operator[](int offset){ return pt[offset]; } const T&operator[](int offset)const { return pt[offset]; } int GetSize()const{ return numsize; } //friend void print(num<T>);//友元 //定义模板友元函数 template<class T1> friend void print(num<T1>); //函数就变成了一个通用的模板友元函数,又叫非约束模板友元函数 private: int numsize; T *pt; }; //这里的template<class T1>是函数所表示的模板 template<class T1> void print(num<T1>sw) { cout<<"friend函数执行!"; for(int i=0; i<sw.GetSize(); i++){ cout<<"num["<<i<<"]:\t"<<sw.pt[i]<<endl; } } //带一个参数的构造函数 template<class T> num<T>::num(int size):numsize(size) { cout<<"执行构造函数"<<endl; pt = new T[size]; for(int i=0; i<size; i++){ pt[i] = 0; } cout<<"numsize:"<<numsize<<endl; } //定义的复制构造函数 template<class T> num<T>::num(const num&r) { numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } //重载运算符= template<class T> num<T>&num<T>::operator=(const num&r) { if(this == &r){ return *this; delete []pt; numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } return *this; } int main() { num<int>one; num<double>two; for(int i=0; i<one.GetSize(); i++) { one[i] = i*2; two[i] = i*5; } print(one); print(two); return 0; }*/ /* // 3 特定类型模板友元函数 #include <iostream> using namespace std; const int size=10; template <template <class T> class TT, class T> ostream & operator<< (ostream &out, const TT<T> &tt); template<class T> class num { public: num(int Tsize=size); num(const num&r); ~num(){delete []pt; } num&operator=(const num&); T&operator[](int offset){ return pt[offset]; } const T&operator[](int offset)const { return pt[offset]; } int GetSize()const{ return numsize; } friend ostream &operator<< <>(ostream &out, const num<T> &tt); private: int numsize; T *pt; }; template<template <class T> class TT, class T> ostream &operator <<(ostream &out, const TT<T> &tt) { out<<"调用operator<<函数"<<endl; for(int i=0; i<tt.GetSize(); i++){ out<<"["<<tt[i]<<"]"<<endl; } return out; } //带一个参数的构造函数 template<class T> num<T>::num(int size):numsize(size) { cout<<"执行构造函数"<<endl; pt = new T[size]; for(int i=0; i<size; i++){ pt[i] = 0; } cout<<"numsize:"<<numsize<<endl; } //定义的复制构造函数 template<class T> num<T>::num(const num&r) { numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } //重载运算符= template<class T> num<T>&num<T>::operator=(const num&r) { if(this == &r){ return *this; delete []pt; numsize = r.GetSize(); pt = new T[numsize]; for(int i=0; i<numsize; i++){ pt[i] = r[i]; } } return *this; } int main() { num<int>one; num<double>two; for(int i=0; i<one.GetSize(); i++) { one[i] = i*2; two[i] = i*5; } cout<<one; cout<<two; return 0; }*/ //该程序与前一个程序同样的结果,不过该程序,也就是在模板类外部声明特定模板友元函数比前一个程序复杂 //1 我们必须在模板类前面声明模板友元函数, //2 在模板类中具体化模板友元函数 //3 为这个特定的模板友元函数提供模板定义