C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板

上传人:E**** 文档编号:89190938 上传时间:2019-05-21 格式:PPT 页数:45 大小:567.50KB
返回 下载 相关 举报
C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板_第1页
第1页 / 共45页
C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板_第2页
第2页 / 共45页
C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板_第3页
第3页 / 共45页
C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板_第4页
第4页 / 共45页
C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板_第5页
第5页 / 共45页
点击查看更多>>
资源描述

《C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板》由会员分享,可在线阅读,更多相关《C++程序设计 教学课件 ppt 作者 郑莉 第14章 _模板(45页珍藏版)》请在金锄头文库上搜索。

1、1,第 14章 模板,清华大学 郑 莉,2,目录,14.1 函数模板 14.2 类模板,3,第14章模板,在C+中有时候会遇到这样的情况:要求实现比较两个double类型数据或两个char类型变量的大小并返回较小值。根据之前学过的知识,我们只能这么写:,char Min(const char a, const char b) return a b ? a : b; double Min(const double a, const double b) return a b ? a : b; ,4,第14章模板,这两个函数几乎相同,仅有的区别在于形参以及返回值的类型,但是函数体是相同的。假如我们需

2、要对更多的类型实现相同的操作,需要定义更多的类似的函数,一来麻烦,二来这样做只能涵盖已知的类型,不能将函数用于未知类型。 C+中,使用了模板(template)的概念来解决上述问题,实现了对于所有的类型,都能完成特定的功能。,5,第14章模板,不管是具有相同功能的函数,还是共有某种功能的类,都可以将多个函数或类汇总,将其所处理的类型也作为一种参数,这种方法叫做参数化多态性,这一概念,在C+中称作泛型编程。,6,14.1函数模板,对于本章开头提到的问题,即对不同类型的变量使用相同的函数操作时,可以用函数模板(function template)实现。,第14章模板,7,14.1.1函数模板的概念

3、、定义与应用,从定义上讲,函数模板是一个独立于类型的函数。从功能上讲,函数模板提供一个在函数调用时可以自动生成各种类型函数实例的算法。形象地说,函数模板就是函数的函数。 函数模板使得代码的可重用性大大提高,从而提高开发效率。在使用函数模板时,程序员只需对函数编写一次,然后基于调用函数时提供的参数类型,自动产生相应的函数来正确处理该类型的数据。,14.1函数模板,8,14.1.1函数模板的概念、定义与应用,函数模板的格式如下: 所有函数模板的定义都以关键字template开始,14.1函数模板,template /*或template */ TYPE Function(parameter1, p

4、arameter2, ., parameter_n) statements;,9,14.1.1函数模板的概念、定义与应用,template后面是使用尖括号()括起来的类型参数列表(template parameter list),类型参数表可以包含一个或多个类型参数(又称模板形参,template parameter),这些类型参数代表的可以是未知的类型,以关键字class或typename修饰,也可以是已知的内置类型或自定义的类(这种情况下不使用class或typename关键字),这样类型参数就可以用来指定模板本身的形参和返回值类型,以及声明函数中的局部变量。 TYPE表示函数的返回类型;

5、Function是函数名,parameter是函数的参数;statements是函数体。,14.1函数模板,10,14.1.1函数模板的概念、定义与应用,例1:函数模板的示例程序。,14.1函数模板,例题要求:了解只包含一个类型参数的函数模板的格式与实例化。 源代码: #include using namespace std; template T Min(const T a, const T b) return a b ? a : b; int main() cout Min(s, f) endl; cout Min(2.5, 4.12) endl; return 0; ,11,14.1.1

6、函数模板的概念、定义与应用,在主函数中,函数Min被调用时,编译器首先根据实际应用中参数的类型推导出模板实参(template argument),自动生成一个函数。每次调用时,执行的实际上是由函数模板生成的函数,这一过程称作函数模板的实例化(instantiate)。,14.1函数模板,运行结果 f 2.5,12,14.1.1函数模板的概念、定义与应用,在上例中,同样可以对自定义类型进行实例化。例如对复数类及其附属的重载运算符实例化(具体实现省略):,14.1函数模板,class Clock friend ostream,13,14.1.2函数模板的实例化,函数模板本身既不是类又不是函数,编

7、译器使用模板产生指定的函数的特定版本,产生模板的特定类型实例的过程称为实例化。 编译器通过查看函数实参的类型和值,确定模板实参的类型和值,来生成函数的实例,这一过程叫做模板实参推断(template argument deduction)。,第14章模板,14,14.1.2函数模板的实例化,编译器在进行模板实参推断的时候遵守以下规则: 在每个实例中必须为每个对应的模板类型参数产生相同的函数实参类型,否则推断失败,编译器报错。 例如Min()函数,下面的调用是错误的: 但是以下的调用是正确的: 也就是说,函数模板实参的推断支持类型转换,这也是十分容易理解的。,第14章模板,Min(s, 97)

8、/错误,模板实参推断失败,Min(s, (char)97) /返回a,a的ASCII码是97,15,14.1.2函数模板的实例化,例2:实现两个不同类型的数相乘,并返回第一个参数类型。,第14章模板,例题要求:了解含有两个类型参数的函数模板的格式与实例化。 源代码: #include using namespace std; template T1 Mul(T1 var1, T2 var2) return (T1)(var1 * var2); ,16,14.1.2函数模板的实例化,第14章模板,int main() cout Mul(3.4, a) endl; /输出为329.8 cout M

9、ul(a, 0.75) endl; /输出为H cout Mul(3, 4.34) endl; /输出为13 return 0; ,运行结果 329.8 H 13,17,14.1.2函数模板的实例化,例3:求一个数组中前N个元素的最小值。,第14章模板,例题要求:了解类型参数中包含基本类型的函数模板的格式,并重点了解其实例化机制。 源代码: #include using namespace std; template T Min(T( ,18,14.1.2函数模板的实例化,第14章模板,int main() int ia = 2, 4, 5, 6, 8, 4, 3; char ca = a,

10、g, k, F, E, t, u, i; cout Min(ia) endl; cout Min(ca) endl; return 0; ,运行结果 2 E,19,14.1.2函数模板的实例化,上例中模板的实例化相对特殊。表面上看,函数参数列表中有两个参数Array与N,然而实际上,根据模板实例化的概念,参数列表中只有一个参数Array是有意义的。所以在实例化时,只需要在函数列表中包含一个参数,编译器将根据Array数组中的元素类型进行模板实参推断。,第14章模板,20,14.1.2函数模板的实例化,通过以上讲解,可以总结出模板实参推断的通用算法如下: 依次检查每个函数实参,确定在每个函数参数

11、的类型中出现的模板参数。 如果找到模板参数,则通过检查函数实参的类型,推断出相应的模板实参。这个过程中允许检查类型转换。 如果在多个函数参数中找到同一个模板参数,则从每个相应函数实参推断出的模板实参必须相同。,第14章模板,21,14.1.3模板实参的省略,在某些情况下,编译器是无法推断出模板实参的类型的。 例如使用前面提到的求两个数较小值的函数模板,如果在主函数中添加如下代码: 再次编译,编译器会报错。提示的原因是无法断定实例化为Min(int, int)还是Min(unsigned int, unsigned int)。模板实参推断失败。,第14章模板,unsigned int ui =

12、100; cout Min(ui, 200) endl;,22,14.1.3模板实参的省略,对于上述问题,应使用显式指定(explicitly specify)模板实参的方法,进行模板实参的“推断”。模板实参显式指定时,应在函数模板实例的名字后面,用尖括号()括起来,列表内部多个类型之间依然用逗号分隔。 例如如果希望T的模板实参是int类型,那么对Min()的调用应该这样写: 模板实参表显式地指定了模板实参的类型。因为模板实参已知,所以在实例化的过程中,ui将被转换成int类型,最后返回一个int类型的结果。,第14章模板,Min(ui, 200) /返回int类型的值100,23,14.1.

13、3模板实参的省略,显式模板参数的其它用途 例如对上节例子中的乘法函数Mul(),指定返回类型的值。如果通过引入第三个模板参数来指明函数模板的返回类型: 因为T1在函数的参数列表中不再涉及,因此如果依然采用旧的调用方式: 编译的时候会报错,原因是没有指定返回值的类型。,第14章模板,template T1 Mul(T2 var1, T3 var2);,Mul(3.4, a);,24,14.1.3模板实参的省略,正确的方法:在调用的过程中给出显式模板实参。,第14章模板,#include using namespace std; template T1 Mul(T2 var1, T3 var2)

14、return (T1)(var1 * var2); int main() cout (3.4, a) (a, 0.75) (3, 4.34) endl; /输出为13.02 return 0; ,25,14.1.3模板实参的省略,第14章模板,运行结果 329.8 72 13.02,26,14.1.3模板实参的省略,上例通过指定显式模板实参给出了返回值的类型。在这个过程中同时也显式指定了两个乘数的类型,然而后者是没有必要的。 编译器可以通过函数实例的参数类型推断出模板实参的类型。所以在实际的编程过程中,后面的模板实参可以省略。对于上例,在实例化的时候可以这样写:,第14章模板,cout (3.

15、4, a) (a, 0.75) (3, 4.34) endl; /输出为13.02,27,14.1.3模板实参的省略,注意,如果要省略模板实参,只能省略后面的一个或几个类型实参,而不能在某个省略的实参后面再指定显式的实参。类似下面这样的指定是错误的:,第14章模板,cout (3.4, a) endl;,28,14.1.3模板实参的省略,显式模板实参与模板实参的省略是两个相关的概念,后者是前者的发展,然而两者的理念并不相同。显式模板实参主要适用于以下两种情况: 从模板函数实参表获得的信息矛盾 需要获得特定类型的返回值,而不管参数的类型如何 但是,一旦指定显式模板实参,则必须检查模板实参对于函数

16、实参是否合适,所以建议在可能的情况下省略模板实参。,第14章模板,29,14.2类模板,类是由变量及有关函数组成的一个封装。一组具有相同功能的函数可以用模板实现,同样地也可以定义类模板(class template),来声明一种类的模式,使得类中的部分成员变量、成员函数的参数或返回值能够取任何内置类型或自定义类型。,14.2类模板,30,14.2.1类模板的概念、定义与应用,类模板就是对具有某些相同性质的不同类的抽象,是类的“家族”。类模板声明的格式如下: 跟函数模板类似,类模板的声明也要以template关键字与模板参数类型列表开始,类型参数列表的规则跟函数模板相同。其后Name为类名,括号里为类的成员。,14.2类模板,template /*或template */ class Name ;,31,14.2.1类模板的概念、定义与应用,如果需要在类模板之外定义其成员函数,则

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号