第二十三模板 15模板和友元

//第二十三模板 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 为这个特定的模板友元函数提供模板定义

  

你可能感兴趣的:(模板)