版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C++程序设计宋存利第九章模板知识点函数模板函数模板定义函数模板的实例化函数模板中的非类型参数重载函数模板类模板类模板的定义类模板的实例化带有非类型参数的类模板模板特化函数模板特化类模板特化模板
模板(template)是代码重用的又一重要手段,是泛型编程的基础,即以一种独立于任何特定数据类型的方式编写代码。模板是对具有相同特性的函数或类的再抽象,是一种参数多态性的工具,可以为逻辑功能相同而类型不同的程序提供一种代码共享的机制。一个模板并非一个实实在在的函数或类,仅仅是对一个函数或类的描述,是参数化的函数和类。9.1函数模板模板就好比我们做月饼的模子,你可放入小麦面团,可放入玉米面团,也可放入大豆面团。放入不同的材质,最终可生产相同图案的不同材质的饼,而不用每次都去重复雕刻相同的图案来做不同材质的饼,这样一个模子就可到处使用,提高了其重用性。C++中模板的概念就是这个原理。请大家考虑“对俩个数求最大值问题”。请问你都会对那些类型的数据求最大值呢?为了解决这些不同数据类型数据的求最大值问题?你会怎么做呢?大部分人的答案:整型、字符型、实型、字符串等,方式函数重载9.1函数模板某同学给的上个问题的答案:intmax(inta,intb)//整数求最大值{returna>b?a:b;}doublemax(doublea,doubleb)//双精度型数据求最大值{returna>b?a:b;}floatmax(floata,floatb)////单精度数据求最大值{returna>b?a:b;}charmax(chara,charb)//字符型数据求最大值{returna>b?a:b;}9.1函数模板发现问题:除了数据类型不同外,重复的代码写了四遍,有没有省力的方法?答案:函数模板定义函数模板的一般语法为:
template<typename标识符1,typename标识符2,...>
返回值类型
函数名(参数列表){//函数体}9.1函数模板
其中,template是定义模板的关键字,尖括号<>用来定义模板的参数,一般叫做模板参数。typename是定义模板参数的关键字,用来说明后面的标识符是一个类型参数。当有多个类型做参数时,它们之间用逗号“,”隔开,并且每个标识符的前面均需要加关键字typename。typename也可用class代替,它们在此处的意义相同,但为了与定义类的关键字class区别,一般建议此处采用typename。“返回值类型
函数名(参数列表)”部分的定义和普通函数定义没有区别。但请注意,模板参数声明的类型参数可用来对函数的返回值、函数圆括号内参数类型以及函数中用到的临时变量进行类型声明。9.1函数模板例如对上面求两个数最大值的问题,定义函数模板,其形式如下:
template<typenameT1>T1max(T1a,T1b){returna>b?a:b;}函数模板一旦声明完成,就可对函数模板进行调用,具体调用表达式格式为:
函数名<类型实参1,类型实参2,...>(实际参数1,实际参数2,...);例如调用函数模板max:cout<<max<int>(3,10);//表达式调用,因max有返回值也可采用如下的调用方法:cout<<max(3,10);//采用表达式调用,此处编译器根据参数3和10的类型确定T1的类型为int9.1函数模板但采用下面的调用语句是错误的。
max(3,11.2);//错误的调用,因为3和11.2类型不一致,因此编译器无法确定T1的类型正确调用可改为:max<double>(3,11.2);//明确告诉编译器T1的类型max<int>(3,11.2);提示:模板实参不允许进行自动类型转换,每个T都必须精确地匹配。【例9-1】函数模板案例,对两个数据进行交换的函数模板。Ninth_1.cpp9.1函数模板-函数模板的实例化
当编译器遇到关键字template和跟在其后的函数定义时,它只是简单的知道这是一个函数模板,除此之外,编译器不会做额外的工作。当编译器遇到对函数模板的调用语句时,它将会根据调用语句中传递的实参的类型,确定模板参数的类型,并用此类型替换函数模板中的模板参数,生成能处理该数据类型的函数的代码,即模板函数,这个过程就是函数模板的实例化。
说明:一旦某函数模板的某个实例化函数产生后,若后面程序中出现了相同的函数模板的调用,则编译器将不再针对该情况反复实例化该模板。9.1函数模板-函数模板的实例化说明1:在实例化函数模板的过程中,模板实参不允许进行自动类型转换;每个T类型的参数都必须精确地匹配。例如有函数模板如下:template<typenameT>voidswap(T&a,T&b){Tt;t=a;a=b;b=t;}若有如下的程序段,系统将提示出错。doublea=12.3;intb=20;swap(a,b);//错误,T的类型无法确定9.1函数模板-函数模板的实例化说明2:当模板参数和调用参数没有发生关联,或者不能由调用参数来决定模板参数时,在调用函数模板时就必须显式指定模板实参。
例如:template<typenameT1,typenameT2>T1max(T2&a,T2&b){T1t;if(a>b)t=a;elset=b;returnt;
}//其调用格式应采用:显然对于函数模板max来说,它有一个模板参数T1无法通过函数的实际参数类型来确定,因此,这时就必须采用显示方式对函数模板进行调用。即:
max<类型参数1,类型参数2>(参数1,参数2)
例如:max(3.2,5.6);//非法,无法确定T1的类型max<int,double>(3.4,5.6);//合法max<double,int>(3,5);//合法
9.1.3函数模板中的非类型参数说明:在函数模板中也可以出现非类型参数,这时在调用函数模板时,必须显示的在函数模板标识符后用尖括号来给模板参数传递实参,而且非类型参数对应的实参必须为常量。提示:非类型参数一般常用int类型,而浮点数和类对象是不允许作为非类型模板参数的。【例9-2】编写函数模板,输出一个数组中的元素值。Ninth_2.cpp9.1.4重载函数模板和普通函数类似,C++中,函数模板也可以重载,但在实际调用过程中,编译器如何确定调用的是函数模板还是普通函数呢?一般编译器采用如下规则来确定调用哪个函数:(1)函数模板会进行严格的类型匹配,模板类型不提供隐式类型转化普通函数能够进行自动类型转换
(2)普通函数和同名的函数模板,如果其他条件都是相同的话,那么在调用时通常会优先调用普通函数。(3)如果函数模板可以产生一个更好的匹配,那么选择模板。(4)可以显式地指定一个空的模板实参列表,这个语法明确告诉编译器,只有模板才能匹配这个调用。9.1.4重载函数模板【例9-3】函数模板的重载以及上述规则的验证。Ninth_3.cpp请参照链接说明了解重载函数模板的规则9.2类模板
类模板的定义与函数模板定义类似,必须先用关键字template开始,后用尖括号“<>”来定义类模板的模板参数,当然也可出现非模板参数,关于非模板参数的约束与函数模板的要求一致。具体类模板的定义格式如下:template<typename类型参数1,typename类型参数2,...>
class类模板名{
//成员函数和成员变量...
};
9.2类模板
其中,关键字template定义的模板参数可用来声明类的数据成员的类型、成员函数的返回值、函数的参数类型等信息,当然这些也可用其他系统内置数据类型或用户自定义数据类型来声明。类模板中的成员函数可以在类中定义,这和普通类的成员函数在类内定义没有区别;也可放在类外面定义,在类外面定义时,其一般格式为:template<typename类型参数1,typename类型参数2,...>
返回值类型
类模板名<类型参数名列表>::成员函数名(参数表)
{
//函数体...
}注意:在类外定义类模板的成员函数时,必须将类模板的声明放在前面。同时,函数名前的作用域说明也需要采用类模板的完整类型限定。类模板的成员函数在类内部定义和普通类的成员函数的定义没有区别。9.2类模板-类模板的实例化类模板一旦定义完成,就可定义具体的对象,其一般语法为:类模板名<真实类型参数表>对象名(构造函数实际参数表);如果类模板有无参构造函数,那么也可以使用如下语法创建对象:类模板名<真实类型参数表>对象名;提示:定义对象的过程就是类模板实例化的过程,也就是实实在在的类生成的过程。在该语句中,必须为类模板中的模板参数在尖括号中传递具体的类型实参,非模板参数传递具体的常量值。注意该过程并不会实例化类中的成员函数,类中的成员函数只有在访问时才会被实例化。【例9-4】类模板案例,在二维坐标中,有离散的整数点,也有连续的实数点,因此设计了二维坐标中的点模板。Ninth_4.cpp9.2类模板-类模板的实例化注意:对应语句“a.display();”,编译器将实例化成员函数display。在该源代码中,没有访问成员函数set,因此set函数将不实例化。也就是说类模板中的成员函数只有在被访问时才实例化,否则不实例化。9.2.3带有非类型参数的类模板同函数模板一样,类模板中也可以带有非类型参数,在类模板实例化时,必须用尖括号来给模板参数传递实参,而且非类型参数对应的实参必须为常量。提示:非类型参数一般常用int类型,而浮点数和类对象是不允许作为非类型模板参数的。[例9-5]带有非类型参数的类模板。ninth_5.cpp9.3*模板特化模板特化不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板的特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。为何要特化模板呢?
原因是模板对某个特定数据类型采用原模板中的处理逻辑将达不到解决问题的目的或有错误,需要特殊对该模板对特定数据类型重新给出其处理逻辑(初学者可略过这里)。9.3*模板特化函数模板特化是在一个统一的函数模板不能在所有类型实例下正常工作时,需要定义类型参数在实例化为特定类型时函数模板的特定实现版本。查看请看【例9-6】。【例9-6】函数模板的特化案例。Ninth_6.cpp说明:在函数模板特化定义中,关键字template和一对尖括号<>不能少,然后是函数模板特化的定义。该定义指出了模板名、被用来特化模板的模板实参,以及函数参数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 任务7.3主梁施工
- 五都赋赏评(冷为峰)
- 介入国际共识全球诊疗统一
- 2026北京中科软DBA面试题及答案
- 2025年中国玻璃联体台盆设备市场调查研究报告
- 2025年中国热压机械市场调查研究报告
- 2025年中国汽车轮胎市场调查研究报告
- 2025年中国摆杆式加料机市场调查研究报告
- 2025年中国1,3,5三烯丙基氰尿醚市场调查研究报告
- 胃息肉术后静脉输液护理要点
- 宝兴县2026年上半年“雅州英才”工程赴外招才引智活动面向全国引进高层次和急需紧缺人才(14人)笔试参考题库及答案解析
- 2025年北京市事业单位联考A类真题试卷及答案
- 2026年南昌市西湖区社区工作者招聘考试参考题库及答案解析
- 山姆会员商店质量溯源体系优化方案
- 架空线路拉线施工技术交底
- 高磷血症患者饮食教育
- 海绵城市建设工程监理实施细则范本
- 不稳定型心绞痛诊疗指南(2025年版)
- 外科洗手小课件
- 2025年会考地理广东真题及答案
- 贵州国企招聘:2025贵州能源集团有限公司第一批综合管理岗招聘41人(公共基础知识)综合能力测试题附答案解析
评论
0/150
提交评论