您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > C++教程第09章模板
1第8章模板8-1.教学目的与要求1.理解模板的概念;2.掌握模板定义和使用方法。8-2.主要内容及重点:通过模板机制可以提供一种通用的方法来开发可重用的代码,即可以创建参数化的C++类型。模模板分为两种类:函数模板和类模板。本章着重介绍有关模板的感念、定义和使用模板的方法等。8-3.第8章模板-课件3-4.8-4.第8章模板-复习总结模板是一种安全的、高效的重用代码的方式。C++有函数模板和类模板,在使用模板时,必须将模板中的模板参数实例化为模板函数和模板类。可以通过在创建对象或函数时传递类型参数的方式决定其行为。每个模板类的实例是一个实际的对象,可以象其他对象一样使用,甚至可以作为函数的参数或返回值。8-5.第8章模板-练习8-5-1.思考题:1).函数模板与重载有什么关系?2).试区分模板函数与函数模板。3).模板函数与重载的普通非模板函数被调用时的匹配先后顺序如何?4).试区分类模板与模板类。5).如何从模板类派生出非模板类?28-5-2.练习题:课后练习题见练习单元。第九章模板通过模板机制可以提供一种通用的方法来开发可重用的代码,即可以创建参数化的C++类型。模板分为两种类:函数模板和类模板。本章着重介绍有关模板的感念、定义和使用模板的方法等。9.1函数模板9.1.1函数模板的概念及说明9.1.1.1函数模板的概念若一个程序的功能仅仅针对某种特定的数据类型进行处理,则可将这些特定的数据类型说明为参数,将该程序说明为模板,这样只要将这些参数指定为任何类型的数据,就可以让该程序对所指定的数据类型进行同样的操作。例定义max()函数,对两个数据进行比较,这两个数据都是整型或实型。intmax(inta,intb){if(ab)returna;elsereturnb;}doublemax(doublea,doubleb){if(ab)returna;elsereturnb;}charmax(chara,charb){...}...为了实现交换各种同类型的数据,需要定义一系列的重载的max()函数,这就给编程人员带来麻烦。一种简单的方法,是将它们写成一个通用的函数(模板),将不同的数据类型抽象为一个通用的参数,在调用过程中再指定具体的数据类型,这样就可以简化程序。实际上,若“提取”出一个可变化的类型参数T,则可“综合”成为如下的同一个函数(模板),它实际上代表着一组函数:3Tmax(Ta,Tb){if(ab)returna;elsereturnb;}在C++中定义完整的函数模板max时,格式如下:templateclassTTmax(Ta,Tb){if(ab)returna;elsereturnb;}9.1.1.2函数模板说明C++允许用户为函数定义模板,称为“函数模板”,当用户需要编写程序代码几乎完全相同的多个重载函数时,可以使用函数模板。函数模板的定义一般形式是:template模板参数表函数返回类型函数名(函数形参表){//函数模板的定义}1)template,关键字表示模板声明;2)模板参数,可以有一个或多个,各参数之间用逗号隔开,模板参数表中的每个参数之前都有关键字class;3)函数返回类型,可以是普通类型,也可以是模板参数表中指定的类型。4)函数形参表,给出函数的若干个参数,它们可以是普通类型,也可以是模板参数表中指定的类型;5)且模板参数表中指明的类型参数一般都要用于函数形参表中,即模板该参数应该出现在上述的“返回类型”或“参数表”或“函数体”中,否则没有可变性,只能定义出一个具体的函数。6)模板的参数还可以实例化为用户自定义类型。函数模板不是一个真实的函数,编译系统不为其产生任何可执行的代码,它只是对函数的描述,表示它每次能单独处理在模板参数表中说明的数据类型。当编译系统发现该函数调用(函数名(实参))时,编译系统就会根据实参的类型,判断是否完全匹配函数模板中对应的函数形参表,如果完全匹配,则生成一个重载函数。该重载函数的定义体与函数模板的定义体相同,只是用实参的实际类型去替换函数形参表中与模板参数表相同的数据类型。该重载函数称为模板函数。7)定义函数模板时要注意下面两种常见的错误:templateTTswap(T&a,T&b);//错误,在模板参数前缺关键字classtemplateclassTT*f();//错误,模板参数的类型参数没用于函数形参表中49.1.1.3函数模板的使用(1).函数模板的基本使用①T为该模板的参数,在调用该模板函数时,必须用实际的数据类型进行实例化模板参数T,才能完成具体的函数功能。例:使用前例中的函数模板“templateclassTTmax(Ta,Tb)”inta,b;charc,d;intm1=max(a,b);//调用max(inta,intb)charm2=max(c,d);//调用max(charc,chard)模板参数T实例化为int型,函数模板max实例化后成为模板函数,能实现两个int型类型数据的比较操作。对char同理。②注意:在使用函数模板时,应保证函数的参数与模板函数的参数完全匹配,因为编译器不会给模板函数的参数提供任何形式的转换。如果参数不合法,编译器给出出错信息。例如:intm3=max(a,c);//编译出错,不能生成max(int,char);这里不会利用隐式转换规则将c转换为int类型。(2).函数模板与函数重载定义一个函数模板与一个函数,它们都叫做min,C++允许这种函数模板与函数同名的所谓重载使用方法。但注意,在这种情况下,每当遇见函数调用时,C++编译器都将首先检查是否存在重载函数,若匹配成功则调用该函数,否则再去匹配函数模板。从函数模板产生的模板函数都是同名的,因此编译器可用重载的方法调用相应函数,同时也可以象重载普通函数一样重载模板函数。对于同名的模板函数与重载的非模板函数,编译器采用如下的顺序确定调用哪个函数版本。1)如果某一非模板函数的参数与函数调用的参数一致,则调用这个非模板函数;2)如果从相应模板生成的模板函数中,有一个模板函数的参数与函数调用的参数一致,则调用该模板函数;3)对相应参数转换之后再匹配非模板函数。4)重载的非模板函数intmax(int,int)使得模板max不能生成模板函数intmax(int,int),因为重载的非模板函数具有优先匹配权。例上例:假设另外增加一个非模板函数intmax(int,int),则有如下的调用方式:inta,b;charc,d;intm1=max(a,b);//调用重载的普通非模板函数intmax(int,int)charm2=max(c,d);//调用函数模板生成的charmax(char,char)intm3=max(a,c);//将c转换成int后调用重载的非模板函数intmax(int,int)(3).二函数模板重载定义两个函数模板,例如它们都叫做sum,都使用了一个类型参数Type,但两者的形参个数不同,C++允许使用这种函数模板重载的方法。5注意,参数表中允许出现与类型形参Type无关的其它类型的参数,如“intsize”。9.1.2函数模板的应用举例(1).函数模板例1定义一个函数模板max,而后对它进行不同的调用。//P302program9–1.cpp#includeiostream.htemplateclassTTmax(Ta,Tb){if(ab)returna;elsereturnb;}voidmain(){inti1=-11,i2=0;doubled1,d2;coutmax(i1,i2)endl;//由实参i1,i2,系统可确定“类型形参T”对应于intcoutmax(23,-56)endl;coutmax('f','k')endl;cind1d2;coutmax(d1,d2)endl;//coutmax(23,-5.6)=max(23,-5.6)endl;//出错!不进行实参到形参类型的自动转换}程序执行后的显示结果如下:0//inti1=-11,i2=0;=max(i1,i2)=023//max(23,-56)=23k//charc1='T',c2='F';=max(c1,c2)=Tmax('f','k')=k123.45//inputdoubled1,d2:123.4599.67d1=123.45,d2=99.67=max(d1,d2)=123.45(2).函数模板例2--//P303program9-2.cpp#includeiostream.h#includestring.h//函数模板min,求出a与b中小者返回,a、b应可进行“”运算templateclasstypetypemin(typea,typeb){//type型的a与b要能够进行“”比较运算!return(ab?a:b);}char*min(char*a,char*b){//函数min,字符串型参数,不能直接使用“”来进行比较return(strcmp(a,b)0?a:b);}voidmain(){coutmin(3,-10)endl;//使用函数模板coutmin(2.5,99.5)endl;////使用函数模板coutmin('m','c')endl;//使用函数模板char*str1=TheCprogram,*str2=TheC++program;6coutmin(str1,str2)endl;//使用重载函数!}运行结果:-102.5fTheCprogram例重载模板函数max的综合应用实例#includeiostream.h#includestring.hclassPoint{//类Point的定义intx,y;public:point(void){x=0;y=0;}point(inti,intj){x=i;y=j}friendintoperator(Point&a,Point&b);//对Point类进行重载运算符‘’friendostream&operator(ostream&os,Point&rp);};intoperator(Point&a,point&b){intdistance;distance=a.x*a.x+a.y*a.y-b.x*b.x-b.y*b.y;//判断两坐标离原点距离的长短returndistance0?1:0;}ostream&operator(ostream&os,point&p){cout”p(“p.x”,“p.y”)”;//输出的Point对象的坐标(x,y)值returnos;}templateclassTTmax(T&a,T&b)//定义函数摸板max{returnab?a:b}char*max(char*a,char*b)//重载摸板函数max用来比较两个字符串{return(strcmp(a,b)0?a:b);}voidmain(){inta=3,b=5;charc=‘E’,d=‘G’;Pointp1(3,5),p2(2,8);cout”(1)max(a,b)is:”max(a,b)endl;//调用摸板函数intmax(int,int)cout”(2)max(c,d)is:”max(c,d),endl;//调用摸板函数charmax(char,char)7cout”(3)max(p1,p2)is:”max(p1,p2)endl;//调用摸板函数Pointmax(Point,Point)cout”(4)max(s1,s2)is“max(“Hello“,“Welcome“)endl;//调用重载非摸板函数char*max(char*,char*)}执行结果:(1)max(a,b)is5(2)max(c,d)isG(3)max(p1,p2)isp(2,8)(4)m
本文标题:C++教程第09章模板
链接地址:https://www.777doc.com/doc-2904253 .html