当前位置: 首页 > news >正文

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

  

相关文章:

  • Android之loader
  • 第六天之还得接着采集
  • Emacs的haskell-mode的安装
  • 网络时间协议 --- 网络对时程序
  • Cocoa、Foundation、UIKit的概念
  • 想象你在镜子前,请问,为什么镜子中的影像可以颠倒左右,却不能颠倒上下?...
  • 浏览器是怎样工作的:渲染引擎,HTML解析(连载二)
  • NoSQL数据库大全收集整理
  • Android对象封装及按汉语拼音排序
  • 虚拟目录
  • Tomcat StringManager阅读学习 -我们到底能走多远系列(10)
  • robots协议
  • 使用ManageEngine NetFlow Analyzer监控netflow
  • 一个超棒的帮助你了解科技公司如何盈利的网站 - rcs.seerinteractive.com
  • 选IDC需注意五点 服务器托管的综合优势
  • 11111111
  • Angular 响应式表单 基础例子
  • classpath对获取配置文件的影响
  • Consul Config 使用Git做版本控制的实现
  • ES2017异步函数现已正式可用
  • input的行数自动增减
  • input实现文字超出省略号功能
  • Java Agent 学习笔记
  • javascript 总结(常用工具类的封装)
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • Java新版本的开发已正式进入轨道,版本号18.3
  • java正则表式的使用
  • JS专题之继承
  • PAT A1017 优先队列
  • SpiderData 2019年2月23日 DApp数据排行榜
  • spring学习第二天
  • 百度地图API标注+时间轴组件
  • 不上全站https的网站你们就等着被恶心死吧
  • 记录一下第一次使用npm
  • 前端_面试
  • 前端性能优化--懒加载和预加载
  • 区块链技术特点之去中心化特性
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 探索 JS 中的模块化
  • 跳前端坑前,先看看这个!!
  • 小试R空间处理新库sf
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 1.Ext JS 建立web开发工程
  • 带你开发类似Pokemon Go的AR游戏
  • 回归生活:清理微信公众号
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • 我们雇佣了一只大猴子...
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • ( 10 )MySQL中的外键
  • (NSDate) 时间 (time )比较
  • (二)windows配置JDK环境
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (原創) 是否该学PetShop将Model和BLL分开? (.NET) (N-Tier) (PetShop) (OO)