函数模板
函数模板就是功能相似的函数写成统一的形式,但是函数的形参类型不同。
函数模板的定义:
template <class T>或者 template<typename T> 类型名 函数名 (参数名) {
函数体的定义
}
函数模板都是以关键字template 开始的,<>中的是类型参数表,每个类型参数,例如上文的“T“,代表的是类型,可以是内部类型(?,指的是函数内部吗?)或者自定义类型,类型参数用来指定函数模板本身的形参类型和返回值类型,以及声明函数中的局部变量(?,什么意思?)。模板中的函数体的定义方式以普通函数定义形式相同。
函数模板使用实例如下:
#include<iostream> using namespace std; template<class T> //声明函数模板 void outputArray(const *P_array, const int count )//定义函数体 { for(int i =0; i<count;i++) cout<<P_array[i]<<" "; cout<<endl; } int main() { const int aCount =8,cCount=20; int aArray[aCount]={1,2,3,4,5,6,7,8}; double bArray[ bCount ]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8}; char cArray[cCount]="Welcome to see you!"; cout <<"a Array contains:"<<endl; outputArray(aArray,aCount); cout <<"b Array contains:"<<endl; outputArray(bArray,bCount); cout <<"c Array contains:"<<endl; outputArray(cArray,cCount); }
分析:
函数模板中的声明的类型参数T,表示抽象类型,当编译器检测到程序中调用函数模板outputArray时,便用outputArray的第一个实参的类型替换掉真个模板中定义的T,并建立用来输出指定类型数组的一个完整函数,之后再编译这个新函数。
由此可知,模板函数与重载是密切相关的,从函数模板产生的相关函数都是同名的,编译器用重载的方法调用相应的函数,另外函数模板本身也可以用多种方式重载(?)。
类模板
类是对一组对象的公共性质的抽象,类模板则是对不同类的公共性质的抽象,因此类模板是更高层次的抽象。
类模板
| <抽象>
类
| <抽象>
对象
由下到上这是对象,类,类模板三者之间的关系,对象经抽象得到共同的性质,形成类,多个类又经过抽象得到共同的性质得到类模板。
类模板声明的语法形式:
template <模板参数表> class 类名 { 类成员声明 }
如果需要在类模板以外实现成员函数,需要采用以下形式:
template <模板参数表>
类型名 类名 <T>::函数名(参数表)
其中模板参数表可以包括:
1、class(或者typename) 标识符
2、类型说明符 标识符 指明可以接受一个由“类型说明符”所规定的类型的常量作为参数。
当模板参数表同时包括上述多项内容时,个内容之间以逗号分隔,但(模板类的成员函数必须是函数模板,??)
这里“模板参数表”中的参数与类模板声明时“模板参数表”中的参数一一对应。系统会根据制定的参数类型和常量值生成一个类,然后建立该类的对象。也就是说,对模板进行实例化生成类,在对类实例化生成对象。但是类模板的实例化过程在程序中是隐藏的,不会出现。
使用模板类来建立对象时,形式如下:
模板<模板参数表> 对象名1,...,对象名n;
类模板的举例:
template<class T>//类模板实现对任意类型数据进行存取 class Store { private: T item; //item用于存放任意类型的数据 int haveValue;//标记item是被存入内容 public: Store(void); //默认形式的构造函数 T GetElement(); //提取数据函数 void PuElem(T x); //存入数据函数 }; //各成员函数的实现 template<class T> //默认形式的构造函数 Store<T>::Store():have Value(0) //因为是构造函数所以没有返回值类 //型 {} //提取函数的实现 template<class T> T Store<T>::GetElement(void) { ////// } template <class T> void Store<T>::PutElem(T x) { haveValue++; item=x; } int main() { Store <int> S1,S2; Store<double> D; S1.PutElem(3); S2.PutElem(-7); }
这部分主要是为了练习类继承的实现形式练习。