第六章模板
第六章 模 板
6.1模板的概念 C++是强类型语言,因此我们定义求最大值函数max()时,需要 对不同的数据类型分别定义不同的版本,例如: int maxint x, int y) i return(x>y)?x: y float max ( float x, float y) [return(x>y)?x: y;] double max double x, double y) ireturn(X>y)?x: y;] 这些函数版本执行的功能都是相同的,只是参数类型和返回类型不 同,能否为上述这些函数只写出一套代码?解决问题的一个方 法就是使用模板。所谓模板,就是写一个函数模子,用这个模子 套印出许多功能相同,参数类型和返回类型不同的函数。模板是 实现了真正的代码可重用性。 可以这么说:函数重载是指用同一个名字定义不同的函数,这些 函数功能不同,执行不同的操作。 函数模板是指用同一个名字定义不同的函数,这些函数功能相同, 而参数类型和返回类型不同
6.1 模板的概念 C++是强类型语言,因此我们定义求最大值函数max()时,需要 对不同的数据类型分别定义不同的版本,例如: int max(int x, int y) { return (x>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;} 这些函数版本执行的功能都是相同的,只是参数类型和返回类型不 同, 能否为上述这些函数只写出一套代码?解决问题的一个方 法就是使用模板。所谓模板,就是写一个函数模子,用这个模子 套印出许多功能相同,参数类型和返回类型不同的函数。模板是 实现了真正的代码可重用性。 可以这么说: 函数重载是指用同一个名字定义不同的函数,这些 函数功能不同,执行不同的操作。 函数模板是指用同一个名字定义不同的函数,这些函数功能相同, 而参数类型和返回类型不同。 1
模板 模板分为函数模板(模子)和类模板(模子),允许用户分别用 它们构造(套印)出(模板)函数和(模板)类。 图显示了模板(函数模板和类模板),模板函数,模板类和对象 之间的关系。 模板 函数模板和类模板)模子 实例化 实例化 模板函 模板类 数 实例化 对象
模板 模板分为函数模板(模子)和类模板(模子),允许用户分别用 它们构造(套印)出(模板)函数和(模板)类。 图显示了模板(函数模板和类模板),模板函数,模板类和对象 之间的关系。 模 板 (函数模板和类模板) 模板函 数 模板类 对象 实例化 实例化 实例化 模子 2
6.2函数模板与模板函数 6.2.1函数模板的声明与模板函数的生成 函数模板的声明格式如下: template class type> 返回类型函数名(参数表) 函数体 其中 template是一个声明模板的关键字,它表示声明一个模板。 关键字 class表明后面的type是模板形参,在使用函数模板时, 必须将其实例化,即用实际的数据类型替代它。 例如,将求最大值函数max()定义成函数模板,如下所示: template T max(TX, Ty return (X>y)? X y;
6.2 函数模板与模板函数 6.2.1 函数模板的声明与模板函数的生成 函数模板的声明格式如下: template 返回类型 函数名(参数表) { 函数体 } 其中template是一个声明模板的关键字,它表示声明一个模板。 关键字class表明后面的type是模板形参,在使用函数模板时, 必须将其实例化,即用实际的数据类型替代它。 例如,将求最大值函数max () 定义成函数模板,如下所示: template T max(T x , T y) { return (x>y)? x:y; } 3
例6.1函数模板的程序 :f include # include≤ string.h> 程序运行结果如下: template the max of i, i2 is: 56 AT max(AT X, AT y) the max of fl f2 is 24.5 i return(x>y)?x: y; y the max of dl. d2 is: 4656.346 void maino the max of cl c2 is a n i int il10, 12=56 float f=12.5,f2=24.5 double b1=50344d2=4656346; char cl=kc2=n cout<< the max of il, 2 is: "<<max(1, 12 <<endl cout<< the max of fl, f2 is: "<<max(f1, f2 <<end; cout<< the max of dl, d2 is: <<max d1, d2 <<endl; cout<” the max of clc2is:“<<max(c1,c2)<≤endl;
例6.1 函数模板的程序 # include # include template AT max(AT x , AT y ) { return (x>y)? X : y; } void main() { int il=10, i2=56; float fl=12.5, f2=24.5; double b1=50.344,d2=4656.346; char c1=’k’,c2=’n’; cout<<”the max of il,i2 is: “<<max(i1,i2)<<endl; cout<<”the max of fl,f2 is: “<<max(f1,f2)<<endl; cout<<”the max of dl,d2 is: “<<max(d1,d2)<<endl; cout<<”the max of cl,c2 is: “<<max(c1,c2)<<endl; } 程序运行结果如下: the max of il,i2 is :56 the max of fl,f2 is :24.5 the max of dl,d2 is :4656.346 the max of cl,c2 is :n 4
函数模板和模板函数的关系 函数模板 max (X, 实例化 实例化实例化实例化 模板函数 模板函数 模板函数 模板函数 max(il, 12) max(f1, f2 max(d1, d2) max(cl,C (1,i2为整型)(f1,2.浮点型(d1,d2为双精型‖(c1,c2为字符型 例6.2与指针有关的模板 include template T sum(T*array, int size=0) T total=O for(int i=0; i<size; i++) total+=array[i] return total
函数模板和模板函数的关系 例 6.2 与指针有关的模板 #include template T sum(T *array, int size=0) { T total=0; for(int i=0; i<size; i++) total+=array[i]; return total; }; 函数模板 max(x,y) 模板函数 max(c1,c2) (c1,c2为字符型 ) 实例化 5 模板函数 max(f1,f2) (f1,f2为浮点型 ) 模板函数 max(d1,d2) (d1,d2为双精型 ) 模板函数 max(i1,i2) (i1,i2为整型) 实例化 实例化 实例化
接1例6.2 int int_ array={1,2,345,6,7,8,9,10} double double_ array={11,22,3344,5.5,6.67788,9.9,10.10}; void maino int itotal=sum int_ array, 10) double dtotal=sum(double- array, 10) cout<< The summary of integer array are <<itotal<<endl; cout≤s” The summary of double array are:"<< dtotal≤<endl; 程序运行结果为: The summary of integer array are: 55 The summary of double array are: 59.6 几点说明: (1)在函数模板中允许使用多个类型参数。但在 template定义部分的 每个模板形参前必须有关键字 class
接1 例6.2 int int_array[]={1,2,3,4,5,6,7,8,9,10}; double double_array[]={1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9,10.10}; void main() { int itotal=sum(int_array,10); double dtotal=sum(double_array,10); cout<<”The summary of integer array are:” <<itotal<<endl; cout<<”The summary of double array are:” <<dtotal<<endl; } 程序运行结果为: The summary of integer array are:55 The summary of double array are:59.6 几点说明: ⑴在函数模板中允许使用多个类型参数。但在template定义部分的 每个模板形参前必须有关键字class。 6
几点说明: 例63 include template void myfunc(type1 x, type2 y) cout<<x<<<<y<<end1 void maino myfunc(10,”hao”); myfunc(0.123,10L); 程序运行结果为: 10 hao 0.12310
几点说明: 例6.3 #include template void myfunc(type1 x,type2 y) { cout<<x<<’’<<y<<end1; } void main() { myfunc(10, ”hao”); myfunc(0.123, 10L); } 程序运行结果为: 10 hao 0.123 10 7
(2)在 template语句与函数模板定义语句之间不允许有别的语句。 ∥这是不能编译的 Template int il:;∥错误,不允许有别的语句 T max(TX,T y i return(x>y)? x: y;] (3)模板函数类似于重载函数,只不过它更严格一些而已。函数被重 载的时候,在每个函数体内可以执行不同的动作,但同一函数模板 实例化后的所有模板函数都必须执行相同的动作。 ∥不能做函数模板的 void outdate int i) i cout≤si;} void outdata double d) cout<”d=”<<d≤endl;} 8
⑵在template语句与函数模板定义语句之间不允许有别的语句。 //这是不能编译的 Template int iI; //错误,不允许有别的语句 T max(T x,T y) { return(x>y)? x : y;} ⑶模板函数类似于重载函数,只不过它更严格一些而已。函数被重 载的时候,在每个函数体内可以执行不同的动作,但同一函数模板 实例化后的所有模板函数都必须执行相同的动作。 //不能做函数模板的 void outdate(int i) { cout<<i; } void outdata(double d) {cout<<”d=”<<d<<endl;} 8
6.2.2函数模板的异常处理 虽然函数模板中的模板形参T可以实例化为各种类型,但实例化T的 各模板实参之间必须保持完全一致的类型,否则会发生错误。请 看下面的例子。 Template T max(TX,Ty i return(x>y)?x: y; y void fun(int i, char c) t max i, i) ∥确,调用max(int;int) max(c,c);∥正确,调用max(char,char) max(i, c) ∥误 max(c, i) ∥误 这里出现错误的原因是,如对语句max(i,c) 编译器将先按变量i将T解释为in类型,此后出现的模板实参c不能 解释为int类型时,便发生错误。解决这个问题有以下两种方法 (1).用强制类型转换,如将调用语句 max(i,c);改写成max(,int(c);
6.2.2 函数模板的异常处理 虽然函数模板中的模板形参T可以实例化为各种类型,但实例化T的 各模板实参之间必须保持完全一致的类型,否则会发生错误。请 看下面的例子。 Template T max(T x,T y) { return(x>y)?x:y; } void fun(int i,char c) { max(i,i); //正确,调用max(int,int) max(c,c); //正确,调用max(char,char) max(i,c); //错误 max(c,i); //错误 } 这里出现错误的原因是,如对语句 max(i,c); 编译器将先按变量i将T解释为int类型,此后出现的模板实参c不能 解释为int类型时,便发生错误。解决这个问题有以下两种方法: ⑴采用强制类型转换,如将调用语句 max(i,c); 改写成 max(i,int(c)); 9