C++面向对象程序设计_第6课__模板_第1页
C++面向对象程序设计_第6课__模板_第2页
C++面向对象程序设计_第6课__模板_第3页
C++面向对象程序设计_第6课__模板_第4页
C++面向对象程序设计_第6课__模板_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第3章章 模板模板3.1 模板的概念模板的概念 模板模板 使用使用模板模板可以建立具有可以建立具有通用类型的函通用类型的函数库数库或或类库类库,为一系列逻辑功能相同,为一系列逻辑功能相同而数据类型不同的而数据类型不同的函数函数或或类创建框架类创建框架 模板模板提供了一种重用提供了一种重用程序源代码程序源代码的有的有效方法,方便了大规模的软件开发效方法,方便了大规模的软件开发 模板的概念模板的概念 模板模板的本质就是将所处理的的本质就是将所处理的数据类型说明数据类型说明为参数为参数,模板是对具有相同特性的,模板是对具有相同特性的函数函数或或类类的的再抽象再抽象,将程序所处理的数据的,将程序所处

2、理的数据的类型类型参数化参数化,这样可使,这样可使一段程序代码一段程序代码能用于处能用于处理多种理多种不同类型的数据不同类型的数据。 C+程序由程序由类类和和函数函数组成,组成,类类对应对应类模板类模板,函数函数对应对应函数模板函数模板。 引入函数模板引入函数模板 考察三个考察三个Swap()函数,分别用于交换两个函数,分别用于交换两个整型数整型数、交换两个、交换两个浮点实型数浮点实型数以及交换两以及交换两个个双精度实型数双精度实型数 这三个这三个Swap()函数的功能完全一样,只有函数的功能完全一样,只有所处理的数据的类型不同所处理的数据的类型不同 void Swap(int &x,

3、 int &y)/ 交换整型数交换整型数x,yint temp = x; x = y; y = temp;/ 通过循环赋值交换通过循环赋值交换x,yvoid Swap(float &x, float &y)/ 交换浮点实型数交换浮点实型数x,yfloat temp = x; x = y; y = temp;/ 通过循环赋值交换通过循环赋值交换x,yvoid Swap(double &x, double &y)/ 交换双精度实型数交换双精度实型数x,ydouble temp = x; x = y; y = temp;/ 通过循环赋值交换通过循环赋值交换x,

4、y上面通过上面通过函数重载函数重载实现了让实现了让函数函数Swap()处理处理不同类型的数据不同类型的数据,要求交换任何一,要求交换任何一对对同一种类型同一种类型的数据。最好的解决方法是的数据。最好的解决方法是类型参数化类型参数化,这样就得到了,这样就得到了函数模板函数模板。使用函数模板定义如下:使用函数模板定义如下:template / class不是类标识不是类标识,只表明只表明ElemType是类型参数是类型参数void Swap(ElemType &x, ElemType &y)/ 交换交换x,yElemType temp = x; x = y; y = temp;/

5、通过循环赋值交换通过循环赋值交换x,y这样得到可以将这样得到可以将任一类型任一类型ElemType的两个数据进行的两个数据进行互换互换的的函数模板函数模板。引入类模板引入类模板 三个类三个类Integer、Float和和Double分别用来处分别用来处理理整型数整型数、浮点型实数浮点型实数以及以及双精度实型数双精度实型数 这三种类的处理功能完全一样,只有所处这三种类的处理功能完全一样,只有所处理的数据的类型不同理的数据的类型不同 / 声明整型类声明整型类class Integerprivate:/ 数据成员数据成员int num;/ 数据值数据值public:/ 公有函数公有函数Integer

6、(int n = 0): num(n) / 构造函数构造函数void Set(int n) num = n; / 设置数据值设置数据值int Get() const return num; / 返回数据值返回数据值;/ 声明浮点型实数类声明浮点型实数类class Floatprivate:/ 数据成员数据成员float num;/ 数据值数据值public:/ 公有函数公有函数Float(float n = 0): num(n) / 构造函数构造函数void Set(float n) num = n; / 设置数据值设置数据值float Get() const return num; / 返回

7、数据值返回数据值;/ 声明双精度实型数类声明双精度实型数类class Doubleprivate:/ 数据成员数据成员double num;/ 数据值数据值public:/ 公有函数公有函数Double(double n = 0): num(n) / 构造函数构造函数void Set(double n) num = n; / 设置数据值设置数据值double Get() const return num; / 返回数据值返回数据值; 上面实现的三个类的功能相同,处理上面实现的三个类的功能相同,处理不同类型的数据不同类型的数据,采用类,采用类型参数化后就可以型参数化后就可以处理任何类型处理任何类

8、型,这样就得到了,这样就得到了类模板类模板。使用。使用类模板定义如下:类模板定义如下:template class Numberprivate:/ 数据成员数据成员ElemType num;/ 数据值数据值public:/ 公有函数公有函数Number(ElemType n = 0): num(n) / 构造函数构造函数void Set(ElemType n) num = n; / 设置数据值设置数据值ElemType Get() const return num; / 返回数据值返回数据值; 函数模板函数模板或或类模板类模板是对是对一族函数或类的描述一族函数或类的描述,模板是模板是使用使用类

9、型类型参数参数来产生来产生一组函数一组函数或或类类的机制。的机制。3.2 函数模板及模板函数函数模板及模板函数3.2.1 函数模板及模板函数函数模板及模板函数 函数模板函数模板是对一批功能相同的函数的说明,是对一批功能相同的函数的说明,它不是某一个具体的函数,是带有它不是某一个具体的函数,是带有“类型类型参数参数”的一种描述的一种描述 模板函数模板函数是将函数模板内的是将函数模板内的“数据类型参数据类型参数数”取某一个具体的数据类型后得到的取某一个具体的数据类型后得到的具具体函数体函数 函数模板的声明函数模板的声明使用函数模板的方法是先声明函数模板,最后才可以调用模板函使用函数模板的方法是先声

10、明函数模板,最后才可以调用模板函数。函数模板的一般声明格式如下:数。函数模板的一般声明格式如下: template 返回值类型返回值类型 函数模板名函数模板名(形参表形参表) / 函数模板体函数模板体或或template 返回值类型返回值类型 函数模板名函数模板名(形参表形参表) / 函数模板体函数模板体template是一个声明是一个声明模板的关键字模板的关键字class在此处并不表示类的意思,只是借用此关在此处并不表示类的意思,只是借用此关键字表示其后是一个类型参数。键字表示其后是一个类型参数。 class 类型参数名类型参数名1, class 类型参数名类型参数名2, 称为类型形参表称为

11、类型形参表 class和和typename的作用相同,都的作用相同,都是表示是表示“类型名类型名”,二者可以互换,二者可以互换 生成模板函数生成模板函数 在使用函数模板时,用实际的在使用函数模板时,用实际的数据类型数据类型具体化(实例化)具体化(实例化)类型形式参数类型形式参数,再根据,再根据实际参数类型实际参数类型,生成一个具体的,生成一个具体的模模板函数板函数,模板函数模板函数的的函数体函数体与与函数模板函数模板的的函数模板体函数模板体完全完全相同,在程序中真正执行的代码是模板函数的代码相同,在程序中真正执行的代码是模板函数的代码 在使用函数模板生成模板函数时,有两种使用方式:在使用函数模

12、板生成模板函数时,有两种使用方式:函数模板名函数模板名(实参表实参表) 或或函数模板名函数模板名(实参表实参表) 第一种使用方式将根据第一种使用方式将根据实参类型实参类型确定确定类型形式参数类型形式参数的的具体具体类型类型,第二种方式中,第二种方式中,称为称为类型实参表类型实参表,用用类型实参表类型实参表中的中的类型类型来确定来确定类型形式参数具体类型类型形式参数具体类型只有一个类型形参的函数模板只有一个类型形参的函数模板类型形参表与类型实参表通常只包含一个类型,这时函数模板的一般类型形参表与类型实参表通常只包含一个类型,这时函数模板的一般声明格式如下:声明格式如下: template 返回值

13、类型返回值类型 函数模板名函数模板名(形参表形参表) / 函数模板体函数模板体或或template 返回值类型返回值类型 函数模板名函数模板名(形参表形参表) / 函数模板体函数模板体使用函数模板生成模板函数的两种使用方式如下:使用函数模板生成模板函数的两种使用方式如下:函数模板名函数模板名(实参表实参表)或或函数模板名函数模板名(实参表实参表)例例3.1 函数模板定义与模板函数的调用示例。函数模板定义与模板函数的调用示例。template ElemType Max(ElemType x, ElemType y)/ 求求x,y的最大值的最大值return x y ? y : x;/ 返回返回x

14、,y的最大值的最大值int main()/ 主函数主函数main()cout 2和和3的最大值为的最大值为 Max(2, 3) endl;/ 输出输出2,3的最大值的最大值/ cout 2和和3.0的最大值为的最大值为 Max(2, 3.0) endl;/ 错错,无法根据无法根据2,3.0确定类型形式参数的具体类型确定类型形式参数的具体类型cout 2和和3.0的最大值为的最大值为 Max(2, 3.0) endl;/ 输出输出2,3.0的最大值的最大值system(PAUSE);/ 调用库函数调用库函数system( ),输出系统提示信息,输出系统提示信息return 0; / 返回值返回值

15、0, 返回操作系统返回操作系统程序运行时屏幕输出如下:程序运行时屏幕输出如下:2和和3的最大值为的最大值为32和和3.0的最大值为的最大值为3请按任意键继续请按任意键继续. . .3.2.2 重载函数模板重载函数模板 模板函数模板函数类似于类似于重载函数重载函数,但是同一个函数模板,但是同一个函数模板类型形式参数具体化(实例化)后的所有模板函类型形式参数具体化(实例化)后的所有模板函数必须数必须执行相同的代码执行相同的代码,而,而函数重载函数重载时在每个函时在每个函数体中可以数体中可以执行不同的代码执行不同的代码,当遇到执行的代码,当遇到执行的代码有所不同时,不能简单地套用函数模板,而应像有所

16、不同时,不能简单地套用函数模板,而应像重载普通函数那样进行重载重载普通函数那样进行重载 重载函数模板重载函数模板后,编译器首先后,编译器首先匹配类型完全相同匹配类型完全相同的函数的函数,如果匹配失败,再寻求,如果匹配失败,再寻求函数模板函数模板进行进行匹匹配配 例例3.2 重载函数模板与匹配过程示例。重载函数模板与匹配过程示例。template ElemType Max(ElemType x, ElemType y)/ 求求x,y的最大值的最大值return x y ? y : x;/ 返回返回x,y的最大值的最大值char *Max(char *str1, char *str2)/ 求求st

17、r1,str2的最大值的最大值return strcmp(str1, str2) 0 ? str2 : str1;/ 返回返回str1,str2的最大值的最大值int main()/ 主函数主函数main()cout 2和和3的最大值为的最大值为 Max(2, 3) endl;/ 输出输出2,3的最大值的最大值, 匹配匹配函数模板函数模板cout China与与American的最大值为的最大值为 Max(China, American) endl;/ 输出输出China,American的最大值的最大值, 匹配函数匹配函数system(PAUSE);/ 输出系统提示信息输出系统提示信息ret

18、urn 0; / 返回值返回值0, 返回操作系统返回操作系统程序运行时屏幕输出如下:程序运行时屏幕输出如下:2和和3的最大值为的最大值为3China与与American的最大值为的最大值为China请按任意键继续请按任意键继续. . . 例例3.3 重载函数模板示例。重载函数模板示例。template ElemType Max(ElemType x, ElemType y)/ 求求x,y的最大值的最大值return x y ? y : x;/ 返回返回x,y的最大值的最大值template ElemType Max(ElemType x, ElemType y, ElemType z)/ 求求

19、x,y,z的最大值的最大值ElemType m = x y ? y : x;/ m为为x,y的最大值的最大值m = m z ? z : m;/ m,z的最大值的最大值return m;/ 返回最大值返回最大值template ElemType Max(ElemType a, int n)/ 求求a0,a1,.,an-1的最大值的最大值ElemType m = a0;/ 假设假设a0为最大值为最大值for (int i = 1; i n; i+)if (m ai) m = ai;/ 如如ai更大更大,则将则将ai赋值给赋值给mreturn m;/ 返回最大值返回最大值int main()/ 主函

20、数主函数main()int a = 1, 9, 7, 5, 6, 3;/ 定义数组定义数组acout 数组数组a的最大元素值为的最大元素值为 Max(a, 6) endl;cout 2和和3的最大值为的最大值为 Max(2, 3) endl;cout 2,3和和8的最大值为的最大值为 Max(2, 3, 8) endl; system(PAUSE);/ 输出系统提示信息输出系统提示信息return 0; / 返回值返回值0, 返回操作系统返回操作系统程序运行时屏幕输出如下:程序运行时屏幕输出如下:数组数组a的最大元素值为的最大元素值为92和和3的最大值为的最大值为32,3和和8的最大值为的最大

21、值为8请按任意键继续请按任意键继续. . .3.3 类模板及模板类类模板及模板类 类模板及模板类类模板及模板类 类模板类模板与与函数模板函数模板类似,它可以为类似,它可以为任意数任意数据类型据类型定义一种定义一种模板模板,使用不同的,使用不同的数据类数据类型型具体化(实例化)具体化(实例化)类模板类模板生成具体的生成具体的模模板类板类 模板类模板类可以用于生成具体的可以用于生成具体的对象对象 3.3.1 类模板的声明及生成模板类类模板的声明及生成模板类 定义一个类模板与定义函数模板的格式类似,必须以关键定义一个类模板与定义函数模板的格式类似,必须以关键字字template开始,类模板的一般声明

22、形式如下:开始,类模板的一般声明形式如下:template class 类模板名类模板名 / 类模板体类模板体; 或或template class 类模板名类模板名 / 类模板体类模板体;类模板的声明类模板的声明 类模板类模板的成员函数不但可以在的成员函数不但可以在类模板内定义类模板内定义,也可以在,也可以在类模板类模板外定义外定义。在类模板外定义时,需要采用下面的形式:。在类模板外定义时,需要采用下面的形式:template 返回值类型返回值类型 类模板名类模板名:成员函数名成员函数名(形参表形参表) / 函数体函数体 或或template 返回值类型返回值类型 类模板名类模板名:成员函数名

23、成员函数名(形参表形参表) / 函数体函数体生成模板类生成模板类 类模板类模板必须用实际的必须用实际的数据类型数据类型具体化(实具体化(实例化)例化)类型形式参数类型形式参数,再根据实际参数类,再根据实际参数类型,生成一个具体的型,生成一个具体的模板类模板类,然后才能用,然后才能用来生成具体对象。来生成具体对象。 一般语法格式如下:一般语法格式如下:类模板名类模板名 对象名对象名;例例3.4 使用类模板的实例。使用类模板的实例。/ 声明数组类模板声明数组类模板template class Arrayprivate:/ 数据成员数据成员ElemType *elem;/ 存储数据元素值存储数据元素

24、值int size;/ 数组元素个数数组元素个数public:/ 公有函数公有函数Array(int sz): size(sz) elem = new ElemTypesize; / 构造函数构造函数Array() delete elem; / 析构函数析构函数void SetElem(ElemType e, int i);/ 设置元素值设置元素值ElemType GetElem(int i) const;/ 求元素值求元素值;例例3.4 使用类模板的实例。使用类模板的实例。template void Array:SetElem(ElemType e, int i)/ 设置元素值设置元素值 i

25、f (i = size)cout 元素位置错元素位置错! endl;exit(1);/ 退出程序的运行退出程序的运行,返回到操作系统返回到操作系统elemi = e;/ 设置元素值为设置元素值为etemplate ElemType Array:GetElem(int i) const/ 求元素值求元素值 if (i = size)cout 元素位置错元素位置错! endl;exit(2);/ 退出程序的运行退出程序的运行,返回到操作系统返回到操作系统return elemi;/ 返回元素值返回元素值elemi例例3.4 使用类模板的实例。使用类模板的实例。int main()/ 主函数主函数m

26、ain()int a = 1, 9, 7, 5, 6, 3;/ 定义数组定义数组aint n = 6;/ 数组元素个数数组元素个数Array obj(n);/ 定义数组对象定义数组对象int i;/ 定义临时变量定义临时变量for (i = 0; i n; i+)obj.SetElem(ai, i);/ 设置数组元素值设置数组元素值for (i = 0; i n; i+)cout obj.GetElem(i) ; / 输出元素值输出元素值cout endl;/ 换行换行system(PAUSE);/ 输出系统提示信息输出系统提示信息return 0; / 返回值返回值0, 返回操作系统返回操作

27、系统程序运行时屏幕输出如下:程序运行时屏幕输出如下:1 9 7 5 6 3请按任意键继续请按任意键继续. . .3.3.2在类型形参表中包含常规参数的类在类型形参表中包含常规参数的类模板模板 在声明类模板的在声明类模板的类型形参表类型形参表中还可以包含中还可以包含常规参数常规参数,常规参数经常是数值。,常规参数经常是数值。 对模板类进行具体化对模板类进行具体化(实例化实例化)为模板类时给为模板类时给这些这些常规参数常规参数所提供的表达式必须是所提供的表达式必须是常量常量表达式表达式。 例例3.5 使用在类型形参表中包含常规参数的实例。使用在类型形参表中包含常规参数的实例。/ 声明数组类模板声明数组类模板template class Arrayprivate:/ 数据成员数据成员ElemType elemsize;/ 存储

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论