模板泛型编程基础_第1页
模板泛型编程基础_第2页
模板泛型编程基础_第3页
模板泛型编程基础_第4页
模板泛型编程基础_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

1、第06章模板泛型编程基础,-2-,本章内容安排,什么是模板 函数模板 类模板 通用数组类UniversalArray 雇员管理系统版本6 (基于模板),-3-,引入问题,问题:多个函数的参数个数相同,处理代码雷同,但处理的数据类型不同 解决方案一:为不同函数设置不同的名字 int imax(int a, int b) return ab?a:b; long lmax(long a, long b) return ab?a:b; double dmax(double a, double b) return ab?a:b; ,存在多个函数版本,代码重复,函数命名复杂混乱,客户 代码难以使用。,-4

2、-,引入问题,解决方案二:函数重载 int max (int a, int b) return ab?a:b; long max (long a, long b) return ab?a:b; double max (double a, double b) return ab?a:b; ,解决函数命名问题,多个函数有统一命名,但代码冗余, 存在多个雷同的实现,维护的代价高。,-5-,解决之道:模板技术,模板技术:将函数参数类型提取出来作为“类型参数”,通过创建通用的函数模板,避免函数体的重复定义。 模板技术适用与类模板,将类中所处理的数据类型提取出来作为“类型参数”,创建通用的类模板。,-6-

3、,本章内容安排,什么是模板 函数模板 类模板 模板应用实例 通用数组类UniversalArray 雇员管理系统版本6(基于模板),-7-,定义函数模板,template T ,max定义了一个模板(并不是一个函数),描述了函数的 骨架,比较2个值并返回大者,两个值通过a和b传递, 而参数类型还没确定,用模板参数T来代替。,标志模板的开始,同时指定模板中使用的类型参数,-8-,调用函数:函数模板实例化,#include int main() std:cout max(3,6) std:endl; char c1=a; char c2=b; std:cout max(c1,c2) std:end

4、l; return 0; ,调用max函数,编译器根据实参类型和函数模板的骨架,生 成针对不同参数类型的max函数版本(函数实例)。 实际生成max和max2个版本函数,如果客户程序 中不调用max,则可能不生成任何函数实例。,-9-,函数模板与模板函数,在编译阶段,编译器根据函数调用时实参的类型以及函数模板,生成实际的函数定义,再进行编译。 函数模板:通用的函数模板,支持类型参数化,是产生实际函数定义的模板。 模板函数:调用函数时根据实参的类型,编译器生成函数实例并对其进行编译。,-10-,编译器生成的函数实例,int max(int const ,通过模板技术,我们只需要维护1份代码骨架,

5、由编译器 编译时替我们生成代码,解决了代码冗余、难以维护等 问题。,-11-,模板参数的演绎,template T ,当编译器无法推断类型参数时,就会出现二义性,从而 报错。 4是int型,4.2是double类型,无法决定T的类型。,X,-12-,显式指定模板参数类型,template T ,在可能出现二义性的情况下,显式指定模板那参数类型, 是一种良好编程习惯。,-13-,本章内容安排,什么是模板 函数模板 类模板 通用数组类UniversalArray 雇员管理系统版本6 (基于模板),-14-,类模板的定义,template class Exam public: void setVal

6、ue (T const,Exam并不是一个真正的类,只是一个类模板(生成类定义 的骨架),类中数据成员和部分成员函数参数的类型还 没有确定,并以模板并没有定义任何类。,标志模板的开始,同时指定模板中使用的类型参数,-15-,类模板的定义,template void Exam :setValue(const T ,类作用域限定符不再是Exam,Exam不是真正的类,真正的 类是按照T类型实例化后的类,名称为Exam。,每个成员函数之前都要使用模板标志,哪怕该函数不使用类型参数。,-16-,定义对象:类模板实例化,#include int main() Exam e1; e1.setValue(5

7、); std:cout e2; e2.setValue(5.5); std:coute2.getValue()std:endl; return 0; ,创建对象时,编译器根据指定的类型,生成特定类型的 类定义(含成员函数实现)。 根据类骨架,编译器针对不同类型帮我们生成类定义。,-17-,编译器生成的类实例,class Exam public: void setVal (int const ,借助模板的强大功能,我们无需编写多个类,编译器根据 类型参数帮我们生成实际需要的类。,-18-,编译器生成的类实例,class Exam public: void setVal (double const

8、 ,-19-,本章内容安排,什么是模板 函数模板 类模板 通用数组类UniversalArray 雇员管理系统版本6 (基于模板),-20-,1、不同数组类的尴尬,3个不同的数组类 Array1D:以int为数据成员,动态内存分配 ArrayEmployee:以Employee为数据成员,动态内存分配 ArrayEmployee:以Employee*为数据成员,动态内存分配 3个数组类,只是处理的数据类型不同,但整个处理逻辑和接口类似,应使用模板技术。,-21-,2、模板数组类的定义,template class UniversalArray public: UniversalArray(in

9、t maxSize=1); UniversalArray(const UniversalArray,此时Array变成了模板,而不是真正 的类,编译器将根据模板,帮助我 们生成所需要的类。,-22-,模板数组类的定义,template class UniversalArray private: T *pData; int size; int maxSize; bool validIndex(int index)const; void copyData(T *data,int maxSize,int curSize); void reAllocMemory(); ;,-23-,成员函数的实现,t

10、emplate void UniversalArray:copyData(T *data, int maxSize,int curSize) int i; this-maxSize=maxSize; size=curSize; pData=new TmaxSize; for(i=0;isize;+i) pDatai=datai; ,每个成员函数前的template声明 都需要保留。 数据元素的类型用T来代替。,鉴于模板的特殊机制,要求将成 员函数的实现和模板定义都放在 头文件中。,-24-,成员函数的实现,template UniversalArray:UniversalArray(int m

11、axSize) this-maxSize=maxSize; pData=new TmaxSize; size=0; template UniversalArray:UniversalArray() delete pData; ,-25-,成员函数的实现,template UniversalArray:UniversalArray( const UniversalArray ,-26-,成员函数的实现,template bool UniversalArray:validIndex(int index)const if(index=size) return false; return true;

12、template void UniversalArray:setValue(int index,T value) if(validIndex(index)=false) return; pDataindex=value; ,-27-,成员函数的实现,template T UniversalArray:getValue(int index) const if(validIndex(index)=false) std:couterror: Invalid index!n; exit(0); return pDataindex; ,-28-,成员函数的实现,template T template c

13、onst T pDatasize=data; size+; template void UniversalArray:reAllocMemory() T *temp=pData; pData=new TmaxSize*2; for(int i=0;isize;+i) pDatai=tempi; deletetemp; ,-30-,成员函数的实现,template void UniversalArray:removeData() if(size=0) std:coutNo data!n; return; size-; ,-31-,成员函数的实现,template void UniversalAr

14、ray:removeData(int index) if(validIndex(index)=false | size=0) return; int i; size-; for(i=index;isize;+i) pDatai=pDatai+1; ,-32-,测试数组类,int main() UniversalArray array1(5); array1.pushData(1); array1.pushData(2); array1.pushData(3); array1.pushData(4); for(int i=0;iarray1.getSize();+i) std:coutarray

15、1i ; std:coutstd:endl; return 0; ,要处理double类型数据,声明Array对象即可, 编译器根据需要创建雷同一致的代码,然后进行编译。,-33-,本章内容安排,什么是模板 函数模板 类模板 通用数组类UniversalArray 雇员管理系统版本6 (基于模板),-34-,问题,int main() UniversalArray array1(5); array1.pushData( new FullTimeEmployee(); array1.pushData(new PartTimeEmployee(); for(int i=0;iarray1.getS

16、ize();+i) std:coutarray1i ; std:coutstd:endl; return 0; ,如果使用Employee *作为数据成员,则通用数组类的析构 函数、拷贝构造函数、赋值运算存在内存问题。 提供三种简单但不太完美的解决方案,其中模板特化的 方法更有普遍性。,-35-,1、继承方法,class ArrayEmployee: public UniversalArray public: ArrayEmployee(int maxSize); ArrayEmployee(); void removeData(); void removeData(int index); A

17、rrayEmployee(const ArrayEmployee,继承并重写实例化类UniversalArray中存在 问题的方法。,-36-,2、二级指针成员方法,template class UniversalArray public: UniversalArray(int maxSize=1); UniversalArray(const UniversalArray,改写UniversalArray,以处理 存储指针这一特殊情况。,-37-,模板数组类的定义,template class UniversalArray private: T *pData; int size; int maxSize; bool validIndex(int index)const; void copyData(T *data,int maxSize,int curSize); void reAllocMemory(); ;,-38-,3、模板特化,template class UniversalArra

温馨提示

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

评论

0/150

提交评论