《第三章模板优秀PPT.ppt》由会员分享,可在线阅读,更多相关《第三章模板优秀PPT.ppt(36页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第三章模板第三章模板现在学习的是第1页,共36页本章主要内容本章主要内容l模板概念模板概念l函数模板及模板函数函数模板及模板函数l类模板及模板类类模板及模板类现在学习的是第2页,共36页3.1 模板的概念模板的概念l模板是模板是C+提供的一种程序框架提供的一种程序框架l当需要重载的函数或有两个以上类仅当需要重载的函数或有两个以上类仅仅只是数据类型不同,函数代码或类仅只是数据类型不同,函数代码或类结构完全相同时,可以只编写一个通结构完全相同时,可以只编写一个通用的函数定义或通用的类定义用的函数定义或通用的类定义l此通用函数定义或类定义即称为此通用函数定义或类定义即称为模板模板l模板提供了一种重用
2、程序源代码的有模板提供了一种重用程序源代码的有效方法,方便了大规模的软件开发效方法,方便了大规模的软件开发现在学习的是第3页,共36页3.1 模板的概念模板的概念l例:有以下函数重载:例:有以下函数重载:int abs(int x)return x 0?x:x;float abs(float x )return x 0?x:x;l此两函数函数体完全一样仅只参数及此两函数函数体完全一样仅只参数及函数类型不同,可只编写一个通用函函数类型不同,可只编写一个通用函数函数模板,由系统自动根据模板数函数模板,由系统自动根据模板创建上两个函数创建上两个函数现在学习的是第4页,共36页3.1 模板的概念模板的
3、概念l例:有以下类定义:例:有以下类定义:class Integerprivate:int num;public:Integer(int n=0):num(n)void Set(int n)num=n;int Get()const return num;class Doubleprivate:double num;public:Double(double n=0):num(n)void Set(double n)num=n;double Get()const return num;l类结构完全相同仅成员类结构完全相同仅成员类型不同,可只编写一类型不同,可只编写一个类模板个类模板现在学习的是第5
4、页,共36页3.1 模板的概念模板的概念l使用模板的程序,编译系统会根据程使用模板的程序,编译系统会根据程序具体情况自动为程序从模板复制重序具体情况自动为程序从模板复制重载出相应的函数或创建相应的类载出相应的函数或创建相应的类l系统重载函数或重新定义类时是根据系统重载函数或重新定义类时是根据调用函数时的实参情况或定义对象时调用函数时的实参情况或定义对象时的指定自动重新取数据类型的的指定自动重新取数据类型的l模板分类:模板分类:函数模板函数模板类模板类模板现在学习的是第6页,共36页3.2 函数模板函数模板 函数模板可以用来创建一个通用函数模板可以用来创建一个通用功能的函数,以支持多种函数体相功
5、能的函数,以支持多种函数体相同但形参类型不同的函数重载,进同但形参类型不同的函数重载,进一步简化重载函数的函数体设计一步简化重载函数的函数体设计现在学习的是第7页,共36页3.2 函数模板函数模板l函数模板声明方法:函数模板声明方法:l格式一:格式一:template 函数定义函数定义l格式二:格式二:template 函数定义函数定义l说明:说明:类型参数是用户自起的标识符,用于在后面类型参数是用户自起的标识符,用于在后面函数定义中代表类型名函数定义中代表类型名两种格式无实质差别仅为习惯两种格式无实质差别仅为习惯 函数模板的声明现在学习的是第8页,共36页3.2 函数模板函数模板l例:求不同
6、类型数据的绝对值函数模例:求不同类型数据的绝对值函数模板板template T abs(T x)return x 0?x:x;T代表类型名代表类型名l实际调用时的实际调用时的T具体的类型由函数调具体的类型由函数调用格式决定用格式决定 函数模板的声明现在学习的是第9页,共36页3.2 函数模板函数模板l带模板的函数调用时与普通重载函数带模板的函数调用时与普通重载函数并无不同并无不同l调用格式:调用格式:函数名(函数名(实参表)实参表)函数名函数名(实参表)实参表)l不同格式调用时模板中的类型参数代不同格式调用时模板中的类型参数代表的具体类型决定方式不同表的具体类型决定方式不同格式一:具体类型由实
7、参类型决定格式一:具体类型由实参类型决定格式二:具体类型由格式中指定格式二:具体类型由格式中指定 函数模板的调用现在学习的是第10页,共36页3.2 函数模板函数模板l具体类型决定后系统将根据类型自动具体类型决定后系统将根据类型自动生成重载函数,并将类型参数代换为生成重载函数,并将类型参数代换为具体类型,有多少种类型即生成多少具体类型,有多少种类型即生成多少个重载函数个重载函数l系统根据模板自动生成的函数称为:系统根据模板自动生成的函数称为:模板函数模板函数 函数模板的调用现在学习的是第11页,共36页/no3.2-1.cpp#includetemplateT abs(T x)return x
8、 0?x:x;void main()int n=-5;double d=-5.5;cout abs(n)endl;cout abs(d)endl;求绝对值函数的模板3.2 函数模板函数模板现在学习的是第12页,共36页l说明说明编译器从实参类型推导出函数模板的类型参编译器从实参类型推导出函数模板的类型参数数,然后以函数模板为样板,生成模板函数然后以函数模板为样板,生成模板函数E对调用对调用 abs(n)实参实参n为为 int 型,系统将型,系统将T代换为代换为 int,生成的模板函数为:,生成的模板函数为:int abs(int x)return x 0?x:x;E对对abs(d)d为为 do
9、uble型,型,T代换为代换为 double 生成模板生成模板函数:函数:double abs(double x)return x 0?x:x;l运行结果:运行结果:55.5 休息 前一页 下一页现在学习的是第13页,共36页#includetemplateT add(T x,T y)return x+y;void main()int m=3,n=-5;float a=-1.8,b=-2.9;double c=2.5,d=3.8;cout add(m,n)endl;cout add(a,b)endl;cout add(c,d)endl;函数模板实例例例no3.2-2 用模板简化函数重载用模板简
10、化函数重载3.2 函数模板函数模板结果为:结果为:-2-4.76.3现在学习的是第14页,共36页l问题:下句可否执行?问题:下句可否执行?cout add(c,m)endl;l错误原因:错误原因:T只能代换为一个类型,而只能代换为一个类型,而m与与c类型不一致,类型不一致,系统无法判定真实类型系统无法判定真实类型l改正方法:改用第二种调用格式改正方法:改用第二种调用格式 cout add(c,m)endl;E指定指定T代换为:代换为:double,结果为结果为 5.5或:或:cout add(c,m)endl;E指定指定T代换为:代换为:int,结果为结果为 5 函数模板实例3.2 函数模板
11、函数模板现在学习的是第15页,共36页l改正方法二:设计两个及以上类型参数改正方法二:设计两个及以上类型参数l模板声明格式改为:模板声明格式改为:template函数定义函数定义或:或:template 函数定义函数定义l注意:注意:参数间用逗号分隔参数间用逗号分隔3.2 函数模板函数模板 函数模板声明现在学习的是第16页,共36页3.2 函数模板函数模板l调用格式改为:调用格式改为:函数名(函数名(实参表)实参表)函数名函数名(实实参表)参表)l调用时类型参数调用时类型参数1代换成实参代换成实参1或类型或类型名名1的类型,类型参数的类型,类型参数2代换为实参代换为实参2或或类型名类型名2的类
12、型的类型 函数模板调用改进现在学习的是第17页,共36页l上例,模板改为:上例,模板改为:template T1 add(T1 x,T2 y)return x+y;l调用时调用时T1代换成实参代换成实参1的类型,的类型,T2代换代换为实参为实参2的类型的类型l结果与结果与T1类型一致类型一致3.2 函数模板函数模板现在学习的是第18页,共36页3.3 类模板类模板 类模板类模板与函数模板类似,它为定与函数模板类似,它为定义类提供一种通用格式,其成员类义类提供一种通用格式,其成员类型可以任意型可以任意实际运行时可使用不同的数据类实际运行时可使用不同的数据类型具体化(实例化)类模板生成具型具体化(
13、实例化)类模板生成具体的体的模板类模板类现在学习的是第19页,共36页3.3 类模板类模板l类模板定义格式:类模板定义格式:template class 类名类名 类成员定义,用类型参数指定类型类成员定义,用类型参数指定类型 ;l类型参数表格式:类型参数表格式:1.class 类型参数类型参数1,class 类型参数类型参数2,.2.typename类型参数类型参数1,typename 类型参类型参数数2,.类模板声明现在学习的是第20页,共36页3.3 类模板类模板l类成员函数实现:类成员函数实现:template 函数类型函数类型 类名类名:函数名函数名(形参表形参表)函数体,其中数据类型
14、可用类型参数函数体,其中数据类型可用类型参数 l类型参数表格式:类型参数表格式:1.class 类型参数类型参数1,class 类型参数类型参数2,.2.typename类型参数类型参数1,typename 类型参数类型参数2,.类模板声明现在学习的是第21页,共36页template /类模板:实现对任意类型数据进行存取类模板:实现对任意类型数据进行存取class Store private:T item;/用于存放任意类型的数据用于存放任意类型的数据 int haveValue;/标记标记item是否存内容,为是否存内容,为1有有 public:Store();/默认形式的构造函数默认形式
15、的构造函数 T GetElem();/提取数据函数提取数据函数 void PutElem(T x);/存入数据函数存入数据函数;下一页 前一页 休息 休息类模板定义实例类模板定义实例现在学习的是第22页,共36页template /提取数据函数的实现提取数据函数的实现T Store :GetElem()/如果试图提取未初始化的数据,则终止程序如果试图提取未初始化的数据,则终止程序 if(haveValue=0)cout No item present!endl;exit(1);return item;/返回返回item中存放的数据中存放的数据 下一页 前一页 休息 休息类模板实现实例类模板实现
16、实例现在学习的是第23页,共36页3.3 类模板类模板l类模板的实现类模板的实现 类外定义对象时,根据用户指定决定类类外定义对象时,根据用户指定决定类型参数真正代表的类型,并自动生成相型参数真正代表的类型,并自动生成相应类定义应类定义l对象定义格式:对象定义格式:类模板名类模板名 对对象名象名(实参表实参表)上例:模板类上例:模板类Store可定义对象:可定义对象:Store S1;/对象对象S1中的中的T为为int型型 Store S3;/对象对象S3中的中的T为结构体为结构体Student型型现在学习的是第24页,共36页类模板应用举例类模板应用举例#include#include/结构体
17、结构体Studentstruct Student int id;/学号学号 float gpa;/平均分平均分;类 模 板现在学习的是第25页,共36页template /类模板:实现对任意类型数据进行存取类模板:实现对任意类型数据进行存取class Store private:T item;/用于存放任意类型的数据用于存放任意类型的数据 int haveValue;/用于标记用于标记item是否已被存入内容是否已被存入内容 public:Store();/缺省形式(无形参)的构造函数缺省形式(无形参)的构造函数 T GetElem();/提取数据函数提取数据函数 void PutElem(T
18、 x);/存入数据函数存入数据函数;/缺省形式构造函数的实现缺省形式构造函数的实现template Store :Store()haveValue=0 下一页 前一页 休息 休息现在学习的是第26页,共36页template /提取数据函数的实现提取数据函数的实现T Store:GetElem()/如果试图提取未初始化的数据,则终止程序如果试图提取未初始化的数据,则终止程序 if(haveValue=0)cout No item present!endl;exit(1);return item;/返回返回item中存放的数据中存放的数据 template /存入数据函数的实现存入数据函数的实现
19、 void Store :PutElem(T x)haveValue+;/将将haveValue 置为置为 TRUE,表示,表示item中已存入中已存入数值数值 item=x;/将将x值存入值存入item 下一页 前一页 休息 休息现在学习的是第27页,共36页void main(void)Student g=1000,23;Store S1,S2;Store S3;Store D;S1.PutElem(3);S2.PutElem(-7);cout S1.GetElem()S2.GetElem()endl;S3.PutElem(g);cout The student id is S3.GetE
20、lem().id endl;cout Retrieving object D ;cout D.GetElem()endl;/输出对象输出对象D的数据成员的数据成员/由于由于D未经初始化未经初始化,在执行函数在执行函数D.GetElement()时出错)时出错 下一页 前一页 休息 休息现在学习的是第28页,共36页 下一页 前一页 使用类模板的实例使用类模板的实例template /声明数组类模板声明数组类模板class Arrayprivate:ElemType*elem;/存储数据元素值存储数据元素值int size;/数组元素个数数组元素个数public:Array(int sz):si
21、ze(sz)elem=new ElemType size;/构造函数构造函数Array()delete elem;/析构函数析构函数void SetElem(ElemType e,int i);/设置元素值设置元素值ElemType GetElem(int i)const;/取元素值取元素值;现在学习的是第29页,共36页 下一页 前一页template /设置元素值设置元素值void Array:SetElem(ElemType e,int i)if(i=size)cout 元素位置错元素位置错!endl;exit(1);elem i =e;/设置元素值为设置元素值为etemplate /取
22、元素值取元素值ElemType Array:GetElem(int i)const if(i=size)cout 元素位置错元素位置错!endl;exit(2);return elem i;/返回元素值返回元素值elemi现在学习的是第30页,共36页程序运行结果:程序运行结果:1 9 7 5 6 3请按任意键继续请按任意键继续.int main()int a =1,9,7,5,6,3;int n=6;Array obj(n);/定义数组对象定义数组对象int i;for(i=0;i n;i+)obj.SetElem(ai,i);/设置数组元素值设置数组元素值for(i=0;i n;i+)co
23、ut obj.GetElem(i);/输出元素值输出元素值cout endl;system(PAUSE);return 0;下一页 前一页现在学习的是第31页,共36页3.3 类模板类模板l声明类模板时,在类型形参表中可以加入普通类型声明类模板时,在类型形参表中可以加入普通类型参数,称为常规参数,常规参数经常是数值参数,称为常规参数,常规参数经常是数值例:例:template 其中其中size即为常规参数即为常规参数l常规参数通常时类中不改变的值,类似常量,常规参数通常时类中不改变的值,类似常量,所以系统根据类模板生成模板类时,具体类型所以系统根据类模板生成模板类时,具体类型名部分对应常规参数
24、处必须是名部分对应常规参数处必须是常量表达式常量表达式。上例上例 定义对象时:定义对象时:Array obj 与与 size 对应的参数对应的参数 n 必须是常量必须是常量现在学习的是第32页,共36页类模板中使用常规参数实例类模板中使用常规参数实例template class Arrayprivate:ElemType*elem;/存储数据元素值存储数据元素值public:void SetElem(ElemType e,int i);/设置元素值设置元素值ElemType GetElem(int i)const;/取元素值取元素值;现在学习的是第33页,共36页 下一页 前一页templat
25、e /设置元素值设置元素值void Array:SetElem(ElemType e,int i)if(i=size)cout 元素位置错元素位置错!endl;exit(1);elem i =e;/设置元素值为设置元素值为etemplate /取元素值取元素值ElemType Array:GetElem(int i)const if(i=size)cout 元素位置错元素位置错!endl;exit(2);return elem i;/返回元素值返回元素值elemi现在学习的是第34页,共36页程序运行结果:程序运行结果:1 9 7 5 6 3请按任意键继续请按任意键继续.下一页 前一页int main()int a =1,9,7,5,6,3;const int n=6;/数组大小,使用常量数组大小,使用常量Array obj;/定义数组对象定义数组对象for(int 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;现在学习的是第35页,共36页现在学习的是第36页,共36页
限制150内