您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 第8章 函数模板与类模板
1第8章模板第8章模板2第8章模板8.1模板的概念问题的引入:一些函数的功能相同,唯一的区别只在于处理对象的数据类型不同,若用函数重载实现,则需编写多个函数:例:intmax(inti,intj){returnij?i:j;}floatmax(floati,floatj){returnij?i:j;}charmax(chari,charj){returnij?i:j;}3第8章模板模板运算对象的类型不是实际的数据类型,而是一种参数化的类型,即是把数据类型作为模板的参数。模板是实现代码重用机制的一种工具。4第8章模板函数的形式参数表中某些形式参数的数据类型被参数化即成为函数模板。说明:(1)函数模板本身不是函数,是生成函数的“模板”。经实例化后才得到真正的函数。(2)实例化是指用某一具体的实际数据类型替代模板中的类型参数的过程。函数模板:5第8章模板8.2函数模板与模板函数函数模板的一般说明形式如下:templateclass类型参数返回类型函数名(模板形参表){函数体}每个类型参数之前都有一个关键字class或typename。多个类型参数之间用逗号分隔•8.2.1函数模板的说明6第8章模板例如,将求最大值函数max()定义成函数模板,如下所示:templateclassTYPETYPEmax(TYPEx,TYPEy){return(xy)?x:y;}也可以定义成如下形式:templatetypenameTTmax(Tx,Ty){return(xy)?x:y;}其中,T为类型参数,它既可取系统预定义的数据类型,又可以取用户自定义的类型。函数模板参数表的类型参数可以用于函数返回值,也可用于函数参数表及函数体中。7第8章模板8.2.2函数模板的使用函数模板的使用就是将函数模板的实例化为具体的函数。函数模板的实例化由编译器来完成。编译系统根据函数调用的实际参数类型自动完成函数模板的实例化。当编译系统发现有一个函数调用:函数名(模板实参表);时,将根据模板实参表中的类型生成一个函数即模板函数。该模板函数的函数体与函数模板的函数定义体相同。8第8章模板【例8.1】函数模板的使用。#includeiostream.htemplateclassTTmax(Tx,Ty){return(xy)?x:y;}main(){inti1=10,i2=56;floatf1=12.5,f2=24.5;doubled1=50.344,d2=4656.346;charc1='k',c2='n';coutThemaxofi1,i2is:max(i1,i2)endl;coutThemaxoff1,f2is:max(f1,f2)endl;coutThemaxofd1,d2is:max(d1,d2)endl;coutThemaxofc1,c2is:max(c1,c2)endl;return0;}9第8章模板总结:函数模板提供了一类函数的抽象,代表了一类函数。模板函数表示一具体的函数。10第8章模板#includeiostream.htemplateclassATATsum(AT*array,intsize=0){ATtotal=0;for(inti=0;isize;i++)total+=array[i];returntotal;}•【例8.2】有关指针的函数模板举例。11第8章模板intint_array[]={1,2,3,4,5,6};doubled_array[]={1.1,2.2,3.3,4.4,5.5};main(){intitotal=sum(int_array,6);doubledtotal=sum(d_array,5);coutitotal=itotalendl;coutdtotal=dtotalendl;}12第8章模板1)在函数模板定义template中给出的每一个形式类属参数都必须在函数形参表中至少出现一次:如:templateclassT1,classT2voidfun(T1x,T2y){……}错误的用法:㊀templateclassTYPE㋥templateclassTYPETYPE*func()voidfunc(){……}{TYPEobj;……}2)在template语句与函数模板定义之间不许有别的语句。函数模板定义时应注意的问题:13第8章模板3)调用模板函数时,应保证函数的实参类型与类型参数完全匹配。函数模板在实例化过程中不做任何类型转换。例如:已知函数模板max的两个形参都是类型参数TYPE类型的,则以下两个应用错误:max(10,10.5);//一个实参是整型,另一个是double型,类型不同max(10,obj1);//一个实参是整型,另一个是MY_CLASS类型,都无法实例化4)在函数模板中允许使用多个类型参数。在template定义部分的每个类型参数前必须有关键字class(或typename)。14第8章模板#includeiostream.htemplatetypenametype1,typenametype2voidmyfunc(type1x,type2y){coutx’’yendl;}main(){myfunc(10,hao);myfunc(0.123,10L);return0;}•【例8.3】有两个类型参数的函数模板。15第8章模板(1)模板函数实际上是描述了一组名字相同的函数,这些函数之间以及这些函数与其它同名函数之间都是一种函数重载的关系。(2)重载函数的每个函数体中可完成不同的行为,函数模板的所有实例都完成相同的行为。(3)函数模板也可以重载。【例8.4】函数模板重载。模板函数与重载函数之间的关系:16第8章模板(4)函数模板与同名的非模板函数也可以重载。调用顺序:1)参数完全匹配的非模板函数;2)函数模板,将其实例化,产生模板函数;3)同名函数经参数的自动转换后实现参数匹配。如果以上3种情况都未找到匹配函数,则按出错处理。17第8章模板8.3类模板与模板类类模板允许用户为类定义一种模式,使得类中的某些数据成员,某些成员函数的参数或返回值,能取任意数据类型。18第8章模板定义一个类模板必须以关键字template开始,然后是类名,其格式如下:templateclassType//模板声明class类名{//…类模板定义体};19第8章模板说明:(1)定义模板时应至少确定一个模板参数;(2)类模板的定义格式与类的定义格式相同,包含说明部分和实现部分;(3)类模板中的成员函数都是函数模板。在类体外定义时,其格式如下:template模板参数表T类型名类名T::函数名(参数表){函数体}20第8章模板类模板不是代表一个具体的、实际的类,而是代表着一类类。实际上,类模板的使用就是将类模板实例化成一个具体的类,即为模板类。它的格式为:类模板名实际的类型对象名(参数);21第8章模板【例8.5】栈类模板的使用。#includeiostream.hconstintsize=10;templateclassType//声明一个类模板classstack{public:voidinit(){tos=0;}voidpush(Typech);//参数取Type类型Typepop();//返回类型取Type类型private:Typestck[size];//数组的类型为类型参数Type,inttos;};22第8章模板templateclassType//每个成员函数都要加上模板声明voidstackType::push(Typeob)//类名为stackType{if(tos==size){coutstackisfull;return;}stck[tos]=ob;tos++;}templateclassTypeTypestackType::pop(){if(tos==0){coutstackisempty;return0;}tos--;returnstck[tos];}23第8章模板main(){//定义字符堆栈stackchars1,s2;//创建两个模板参数为char型的对象inti;s1.init();s2.init();s1.push('a');s2.push('x');s1.push('b');s2.push('y');s1.push('c');s2.push('z');for(i=0;i3;i++)coutpops1:s1.pop()endl;for(i=0;i3;i++)coutpops2:s2.pop()endl;24第8章模板//定义整型堆栈stackintis1,is2;//创建两个模板参数为int型的对象is1.init();is2.init();is1.push(1);is2.push(2);is1.push(3);is2.push(4);is1.push(5);is2.push(6);for(i=0;i3;i++)coutpopis1:is1.pop()endl;for(i=0;i3;i++)coutpopis2:is2.pop()endl;return0;}25第8章模板[例8.6]链表类模板。#includeiostream.htemplateclasstypeclasslist{public:list(typed);voidadd(list*node){node-next=this;next=0;}list*getnext(){returnnext;}typegetdata(){returndata;}private:typedata;list*next;};26第8章模板templateclasstypelisttype::list(typed){data=d;next=0;}main(){listcharstart('a');listchar*p,*last;inti;last=&start;for(i=1;i26;i++){p=newlistchar('a'+i);p-add(last);last=p;}coutendl;27第8章模板p=&start;while(p){coutp-getdata();p=p-getnext();}coutendl;return0;}28第8章模板【例题8.7】使用两个类型参数的类模板。#includeiostream.htemplateclassT1,classT2classmyclass{public:myclass(T1a,T2b){i=a;j=b;}voidshow(){couti=ij=jendl;}private:T1i;T2j;};•模板类也可以有多个类型参数。29第8章模板main(){myclassint,doubleob1(12,0.15);myclasschar,char*ob2('x',Thisisatest);ob1.show();ob2.show();return0;}30第8章模板定义类模板CThree储存三个成员变量,成员函数Min返回其中的最小值,成员函数Max返回其中的最大值。templateclassTclassCThree{public:CThree(Tt1,Tt2,Tt3);TMin();TMax();private:Ta,b,c;};31第8章模板#includeiostream.hvoidmain(){CThreeintobj(2,5,4);coutobj.Min()endl;coutobj.Max()endl;CThreedoubleobj2(8.52,-6.75,4.54);coutobj2.Min()e
本文标题:第8章 函数模板与类模板
链接地址:https://www.777doc.com/doc-3357666 .html