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

  

原文地址:https://www.cnblogs.com/xiangxiaodong/p/2711692.html