31 C++ 模版和泛型

前提

我们先来看一类问题,如下的三个方法能否换成一个方法呢?

这就是模版的来历。

int funcadd(int a, int b) {
	return a + b;
}
double funcadd(double a, double b) {
	return a + b;
}

float funcadd(float a,float b) {
	return a + b;
}

模版的概念

所谓泛型编程,是以独立于 任何 特定类型的方式编写代码

这意味着,我们在声明或者定义的时候,不会指定具体的类型。

但是在使用的时候,需要指定具体的类型或者值

模版是泛型编程的基础公式。

模版一般分为 函数模版 和 类模版

函数模版定义:

template
T1 func88(T1 a, T2 b) {
    return a + b;
}

函数模版的定义通常都是在.h文件中

函数模版的调用

int a =10; int b =20;

func88(a,b);

函数模版 的常用方式一:

定义的时候:使用 如下的代码,告知C++编译器:"T 是一种类型,不要报错".

在编译阶段:当编译器看到有函数模版的具体调用的时候,函数模版才会生成具体的函数;

如果没有调用,编译器则不会生成具体的函数;

template

或者

template

函数模版

//如上的三个函数,能写成一个函数会更好,这就是模版存在的意义。
template 
T funcadd(T a, T b) {
	return a + b;
}

void main() {
	int a = 1;
	int b = 2;

	cout << funcadd(a ,b) << endl;

	double a1 = 9.9;
	double b1 = 89.9;
	cout << funcadd(a1, b1) << endl;
}

template 
T1 func88(T1 a, T2 b) {
	return a + b;
}


使用:
	int a2 = 10;
	double b2 = 89.8;
	int a3 = func88(a2,b2);
	cout << a3 << endl;

	int a4 = 1000;
	int a5 = func88(a2, a4);//T1 和 T2 可以一样
	cout << a5 << endl;

函数模版的不常用方式二:

直接在template 上定义了具体的类型。

template
int func89(){
    return a1 + a2;
}

template
int func89(){
	return a1 + a2;
}

void main() {
	cout<()<() << endl;//会有build error。这里其实没有理解,理论上应该知道是啥类型才对
}

类模版定义:

类模版的定义通常都是在.h文件中,

且必须要有类的全部信息 --- 包括类模版中的成员函数的函数体。

和函数模版一样,编译器在实例化模版类时候,编译器就会生成一个具体的类

//类模版
template 
class Teacher89 {

typedef T1* myiterator;
public :
	T m_age;
	myiterator iter;//迭代器

public:
	Teacher89() {
		cout << "空的 构造函数" << endl;
	}

	Teacher89(T age, T1 iter):m_age(age){
		cout << "有两个参数的 构造函数" << endl;
		this->iter = &iter;
	}

//类模版中的成员函数 函数体 写在类模版中,会被声明为inline函数,
	int getInt() {
		return 10;
	}
//类模版中的成员函数 函数体 写在类模版外,只是在类模版中声明
	double getdouble();


//类模版中成员函数如果返回值是 一个模版类行,函数体写在类模版外,只是在类模版中声明
	myiterator getInterator();

//注意的是:即使实例化模版之后,如果没有任何成员函数被使用,类模版中的成员函数也不会被实例化。
//但是当只要有一个 成员函数被使用,那么所有的类成员函数模版都会被实例化

};
template 
double Teacher89::getdouble() {
	return 89.9;
}



template //typename Teacher89::myiterator 声明这玩意是个返回类型
typename Teacher89::myiterator Teacher89::getInterator(){
	return Teacher89::iter;
}

void main() {
	cout << "断点" << endl;
	Teacher89 t89; //模版类的实例化
	//注意的是:Teacher89是类的模版名,Teacher89才是类型名。
	//所以,一个实例化的类型,总会用尖括号<>包含着模版参数

	string abc("nihao");
	Teacher89 t891(80,abc);//模版类的实例化
	cout << t891.getInt() << endl;
	cout << t891.getdouble() << endl;
	cout << t891.getInterator() << endl; // 打印出来的是地址:0x00000077676ffbb8,debug看到在构造函数中 :this->iter = 0x00000077676ffbb8 "nihao"
	cout << "---" << endl;
	cout << *(t891.getInterator()) << endl; //但是这个打印不出来nihao,啥都打印不出来,原因未知???
}

你可能感兴趣的:(c++)