TemPlate (模板)
一. 函数模板(Function Template)
在C++里,我们可以写一个通用函数,使用非实例化的参数类型,该参数在函数被调用时进行实例化。这种函数称为函数模板。
以前我们实现一个函数的时候都会为其写一个独自的方法去实现,就是把所有的代码都写在main函数里,没有任何封装和模块,这样的程序编写风格不是很好,没有充分的实现代码的复用。
eg:int iArray[max] = {10, 20, 30, 40, 50}; float fArray[max] = {1.1, 1.2, 1.3, 1.4, 1.5}; char *cArray[max] = {"one", "two", "three", "four","five"}; sx: for(int i =0;i<max;i++){ cout<<iArray[i]<<“ ”; } for(int i =0;i<max;i++){ cout<<fArray[i]<<“ ”; } for(int i =0;i<max;i++){ cout<<cArray[i]<<“ ”; }
还有一种实现的是对代码的初步复用,就是写一个输出函数对数组进行输出;
void printArray(int* array,int size); for(int i =0;i<max;i++){ cout<<iArray[i]<<“ ”; } printArray(array,max); void printArray(float* array,int size); void printArray(char** array,int size);
我们可以看到这个输出函数的行为是一样的,只是操作的输出类型不同而已.
现在我们使用函数模板写一个通用的函数经行输出操作。
首先我们看一下普通函数和函数模板的区别:
1.普通函数:参数值未定,但参数类型确定. 2.函数模板:不仅参数的值不确定,连参数的类型也不确定,这是一种更高级的复用.
template<class T> ———这就是函数模板的声明
T是类型参数,T是一个未实例化的类型.T有可能是int,float,char*....
void printArray(T* array,int size){ for(int i =0;i<size;i++){ cout<<array[i]; } }
在调用函数模板时,对模板自动进行实例化,模板形参的类型取决于传入的实参的类型。
main: printArray(iArray,max); //在这里T被实例化为int类型 printArray(fArray,max); //在这里T被实例化为float类型 printArray(cArray,max); //在这里T被实例化为char类型
总结:函数模板的作用就是把具有相同功能的函数写成一个模板,这样方便统一管理。
二.类模板 (class template)
通过函数模板我们可以看到,函数模板的参数是不同的;在这里我们可能想到我们以前接触到的许多类,这些类就是参数不同而已,在这里我们可以写一个基础类模板,当一个对象声明的时候,需要给出明确的类型。
函数模板:一个通用函数,可以操作多个类型。
类模板:仅仅是成员变量类型的不同,但是这些成员变量的操作(成员函数)类似.
类模板的声明和实现必须在.h文件中完成。
template <class T>,T是一个类型,未知类型
T* stackPtr; //这里使用的是模板T声明成员函数; 在用int实例化后,可以视为类声明中所有的T用实例化的int类型来替换。
模板类的每个成员函数,都是模板函数; 实现时,每个成员函数前面,都要加上模板声明.
template<class T> Stack<T>::Stack(int …) //对类的构造函数进行初始化,
main:
与函数模板自动实例化不同,函数模板是在调用的时候进行实例化。 而类模板必须在声明该模板的对象时,明确的用指定类型对模板实例化。
//Stack<int> stack; //把模板T,实例化为int类型。
模板参数也可以有默认值。
template<class T = int>模板参数的默认值,即具体的数据类型。
模板参数可以有多个。
(1)template<class T,class S>; (2)template<class T,int max_size>
T是参数化类型。max_size是非类型参数,已经确定类型的模板参数,非类型参数只能是整型,一般用于数组下标。