第六章第六章 模模 板板6.1 模板的概念模板的概念6.2 函数模板与模板函数函数模板与模板函数6.3 类模板和模板类类模板和模板类1 模板是面向对象多态性的一种表现,1990年ANSI C++委员会将模板确定为组成部分,Borland C++ 3.0以上和Visual C++都支持模板 模板包括函数模板和类模板一、为什么要引入模板? 模板的引入一个最重要的目的就是简化编程由于C++是强类型语言,许多类似功能(函数或类)只要数据类型不同,就必须定义多份,不但使源程序增长,工作量也加大2例如,设计一个求两参数最大值的函数,不使用模板时,需要定义四个函数:int max(int a,int b){return(a>b)?a:b;}float max(float a,float b){return(a>b)?a:b;}double max(double a,double b){return(a>b)?a:b;}char max(char a,char b){return(a>b)?a:b;}这些函数的功能甚至语句都类似,能否只写一套代码,使用与多种数据类型呢?6.1 模板的概念36.1 模板的概念 解决的答案就是模板,通过类型参数化来实现代码重用——即把数据类型定义为参数,使用时才给出具体类型来实例化类型参数。
模板分为 函数模板(function template)和类模板(class template)函数模板模板函数实例化类模板模板类实例化4 所谓函数模板,就是写一个函数模子,用这个模子套印出许多功能相同,参数类型和返回类型不同的函数 模板函数:函数模板实例化后的具体函数6.2 函数模板与模板函数66.2.1 函数模板的声明与模板函数的生成函数模板的声明格式如下:template 返回类型 函数名〔模板形参表){ 函数体}type是模板形参,在使用函数模板时,必须将其实例化,即用实际的数据类型替代它6.2 函数模板与模板函数7函数max()若使用模板,则只定义一个函数:template type max(type a,type b){return(a>b)?a:b;} 函数模板定义不是一个实实在在的函数,编译系统不为其产生任何执行代码该定义只是对函数的描述,表示它每次能单独处理在类型形式参数表中说明的数据类型6.2 函数模板与模板函数8//例6.1 #include template T max(T x,T y) {return (x>y)?x:y;} main() { int i1=10,i2=56; float f1=12.5,f2=24.5; double d1=50.344,d2=4656.546; char c1=‘k’,c2=‘n’;6.2 函数模板与模板函数9cout<<“the max of i1,i2=“<y)?x:y;}float max(float x,float y){return(x>y)?x:y;}double max(double x,double y){return(x>y)?x:y;}char max(char x,char y){return(x>y)?x:y;}结果:结果:the max of i1,i2=56the max of f1,f2==24.5the max of d1,d2=4656.546the max of c1,c2=n10函数模板函数模板max(T x,T y)max(T x,T y)模板函数模板函数1 1max(i1,i2)max(i1,i2)实例化实例化1 1T->intT->int模板函数模板函数2 2max(f1,f2)max(f1,f2)实例化实例化2 2T->floatT->float模板函数模板函数3 3max(d1,d2)max(d1,d2)实例化实例化3 3T->doubleT->double模板函数模板函数4 4max(c1,c2)max(c1,c2)实例化实例化4 4T->charT->char函数模板:一组函数的抽象函数模板:一组函数的抽象模板函数:一个具体的函数模板函数:一个具体的函数代码重用,提高了程序设计的效率代码重用,提高了程序设计的效率11例例6.2::#include template T sum(T *array, int size=0) { T total=0; for(int i=0;i
注意定义形式: 每个模板形参前必须加关键字classn 例:template n void myfun(T1 x,T2 y)n { cout<myfun(int,char*)n myfun(0.12345,10L); ---->myfun(double,long int)n(2)在模板template 语句和函数模板定义之间不能有别的语句6.2 函数模板与模板函数136.2.2 6.2.2 函数模板的异常处理函数模板的异常处理实例化T的各模板实参之间必须保持完全一致的类型,否则会发生错误 template T max(T x,T y) {return (x>y)?x:y;} void fun(int i,char c){ max(i,i); //ok max(c,c); //ok max(i,c); //error 无法匹配 max(c,i); //error}模板没有隐含的模板没有隐含的类型转换功能类型转换功能14(1)采用强制类型转换采用强制类型转换 max(i,int(c));(2〕重载函数模板〕重载函数模板 template TT max(T x,T y) {return (x>y)?x:y;} int max (int ,int);----①①只声明原型只声明原型 void fun(int i,char c) { max(i,i); //ok call max (int ,int); max(c,c); //ok call max (char ,char); max(i,c); //ok call max (int ,int); max(c,i); //ok call max (int ,int);}支持隐式类支持隐式类型转换型转换15②②定义一个完整的非模板函数定义一个完整的非模板函数#include#include#include#includetemplatetemplateT max(T x,T y)T max(T x,T y){return (x>y)?x:y;}{return (x>y)?x:y;}char* max(char* x,char* y)char* max(char* x,char* y){return (strcmp(x,y)>0?x:y);}{return (strcmp(x,y)>0?x:y);}void main()void main(){ { cout<<"Max(\"Hello\",\"Gold\")iscout<<"Max(\"Hello\",\"Gold\")is““<
先配外部再配模板再配模板最后转换配外部最后转换配外部6.2.2 6.2.2 函数模板的异常处理函数模板的异常处理17n类模板 (也称为类属类或类生成类)是:允许用户为类定义一种模式,使得类中的某些数据成员,某些成员函数的参数或者返回值,能取任意数据类型n template n class <类名> { n //类说明体 n };n 模板类:类模板实例化成一个具体的类;n 类名<实际的类型> 对象名6.3 类模板与模板类18例:堆栈类模板 const int size=10; template class Stack{ T stk[size]; //堆栈元素类型可变 int top; //记录元素个数,int型不变public: Stack() { top=0; } //创建 void push( T ob); //元素入栈 T pop( ); //元素出栈};19类体外成员函数定义格式: template 返回类型 类名< type > ::函数名(参数表) { 函数体 }在类体外定义成员函数时,若其中用到模板形参,则需要在函数体前进行模板声明,函数名前的类名之后也要缀上< type >。
20例:template void Stack::push( T ob) { if(top==size) { cout<<“Stack full”; return ;} else { stk[top]=ob; top++;} }template void Stack::pop(){ if(top==0) { cout<<“Stack empty”; return ;} top--; return stk[top]; }21例:堆栈类模板使用int main( ){ Stack s1,s2; //Stack s1,s2; s1.push(‘a’); s1.push(‘b’); s1.push(‘c’); s2.push(‘x’); s2.push(‘y’); s2.push(‘z’); cout<<“pop s1:”; for(int i=0;i<3;i++) cout<Stack模板类模板类1 1StackStack实例化实例化1 1T->charT->char模板类模板类2 2StackStack实例化实例化2 2T->intT->int模板类模板类3 3StackStack实例化实例化3 3T->doubleT->double23n使用类模板使用户可以为类定义一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型〔包括系统预定义的和用户自定义的)24实例:数组排序实例:数组排序---函数模板函数模板#include templatevoid sort(T *array,int len){ T temp; for(int i=0;ivoid show(T *array,int len) { for(int i=0;itemplateclass array{ T content[100]; int len; public: array(T*,int); void sort(); void show();};实例:数组排序实例:数组排序---类模板类模板templatearray::array(T *t,int l) { for(int i=0;ivoid array:: sort(){ T temp; for(int i=0;i void array::show() { for(int i=0;i a1(test1,5); arraya2(test2,3); a1.show(); a1.sort(); a1.show(); a2.show(); a2.sort(); a2.show(); return 0;}21 23 13 42 5858 42 23 21 13102.3 45.6 763.29763.29 102.3 45.629本章小结n1.模板的概念及引入n2.函数模板的定义和使用方法n3.类模板的定义和使用方法n4.类模板在c++程序中的主要应用31作业作业n考虑:6.1-6.4n作业:6.5-6.1032。