面向对象的程序设计c++第六章模板演示文档_第1页
面向对象的程序设计c++第六章模板演示文档_第2页
面向对象的程序设计c++第六章模板演示文档_第3页
面向对象的程序设计c++第六章模板演示文档_第4页
面向对象的程序设计c++第六章模板演示文档_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

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

文档简介

面向对象程序设计第六章 模板C+ Templates,杨卫东 左峥嵘华中科技大学 自动化学院,2017秋,参考资料,C+ primer 第四版Effective C+ 3rdC+ Templates(简体中文版).pdf,内容,模板的定义函数模板类模板标准模板库STL,问题提出,实现一个函数,输入2个变量,输出这两个变量中值比较大的元素。要求:此函数可以接受int, char以及double类型的参数。C语言实现:/函数1char MaxOfChar( char cNum1, char cNum2) return(cNum1cNum2)?cNum1:cNum2;/函数2int MaxOfInt( int iNum1, int iNum2) return(iNum1iNum2)?iNum1:iNum2;/函数3double MaxOfDouble( double dNum1, double dNum2) return(dNum1dNum2)?dNum1:dNum2;,C语言,函数重载,c+时代,由于存在重载的概念,所以实现起来应该是这个样子:/函数1char Max( char cNum1, char cNum2) return(cNum1cNum2)?cNum1:cNum2;/函数2int Max( int iNum1, int iNum2) return(iNum1iNum2)?iNum1:iNum2;/函数3double Max( double dNum1, double dNum2) return(dNum1dNum2)?dNum1:dNum2;#define MAX(x,y) ( (xy) ? x: y ),函数名字统一但代码量没有什么变化能否进一步?,C+,宏定义,宏定义#define Max( Inputl, Input2) ( ( InputlInput2) ? Inputl:Input2 )宏无类型检查,不建议,模板(函数模板) templateT Max( const T 可以接受任何类型的参数,包括上边提到的int, char, double,甚至任何自定义类型(只要你实现了它的比较运算符operator ) 具体选用什么样的实际函数是在编译时刻就决定好的,丝毫不会影响运行时的效率,Input参数中用的是const&的,好处是减少函数调用时候的开销,因为我们不知道T类型到底有多大,模板定义,代码重用是程序设计的重要特性,为实现代码重用,使得代码具有更好的通用性,需要代码不受数据类型的限制,自动适应不同的数据类型,实现参数化程序设计。模板是C+中进行通用程序设计的工具之一模板是C+支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型如希望函数或类能够处理多种不同类型数据,可以通过模板为函数或类设计一个通用样板(通用数据类型),当处理实际数据时,根据给定数据的实际类型来确定,模板是c+语言最强大却最少被使用的特征之一,便于重复利用已经开发好的数据结构和算法,可以提高代码的复用性和开发效率,是通用编程实现方法之一。 在c+中,模板让程序员能够定义一种使用不同类型对象的行为。比如用模板类定义一种链表,那么通过不同的模板参数(在调用时提供),可以生成不同类型的链表 有点像宏,但是宏不是类型安全的,而模板是类型安全的分函数模板和类模板两种,模板的特点,6.1 函数模板 1、数据类型作为参数的背景例:求绝对值的函数int abs(int x)return x0?-x:x;double abs(double x)return x0?-x:x;特点:算法完全相同,仅仅只是数据类型不同。(函数重载)问题:能否以数据类型作为参数,实现通用代码设计。,2、模板模板是由可以使用任何数据类型的通用代码构成。模板以数据类型作为参数。模板的定义形式是:template 函数定义说明:template是关键字,表示定义的是模板。括起来的是模板的参数,可以有一个或多个。如:template 或者:template,3、例子 定义一个求绝对值函数的模板。#include template T abs(T x)return x0?-x:x;void main()int n=-5;double d=-5.5;coutabs(n)endl;/由n的类型为int推导出T为intcoutabs(d)endl; /由d的类型为double推导出T为double,分析:编译器调用abs()时,用其实参的类型推导出函数模板的类型参数。当类型参数的含义确定后,编译器将以函数模板为样板,生成一个函数。以abs(n)调用为例,编译器将生成一个函数:int abs(int x)return x, 2 _TD31;,举例2矩阵,template class Matrixpublic: / constructors and destructor Matrix(); Matrix( const Matrix ,Test62_TmatrixsDemo.dsw,模板是C+支持参数化的工具使用类模板使用户可以为类声明一种模式,使类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值能够取任意类型。类模板的声明形式如下: template 类声明模板参数表为:class 标识符;如:template 模板参数表包含上面多项内容时,各项内容以逗号分隔。模板类的成员函数必须是函数模板,6.2 类模板,在类模板首部以外的成员函数定义都要以下面的形式开头。 template 与函数模板相同,类模板只有使用的时候才被具体化为某一种类型用模板类创建对象的一般形式: 模板 对象名1,对象名2,对象名n; 模板参数表为用逗号分隔的若干类型标识符或常量表达式构成。,6.2 类模板,#include #include / 结构体Studentstruct Student int id; /学号 float gpa; /平均分; template /类模板:实现对任意类型数据进行存取class Store private: T item; / item用于存放任意类型的数据 int haveValue; / haveValue标记item是否已被存入内容 public: Store(void); / 缺省形式(无形参)的构造函数 T GetElem(void); /提取数据函数 void PutElem(T x); /存入数据函数;,举例,/以下实现各成员函数。/注意:模板类的成员函数,若在类外实现,则必须是模板函数/ 缺省形式构造函数的实现template Store:Store(void): haveValue(0) / 提取数据函数的实现template T Store:GetElem(void) / 如果试图提取未初始化的数据,则终止程序 if (haveValue = 0) cout No item present! endl; exit(1); return item; / 返回item中存放的数据 ,/ 存入数据函数的实现 template void Store:PutElem(T x) haveValue+; / 将haveValue 置为 TRUE,表示item中已存入数值 item = x; / 将x值存入itemvoid main(void) Student g= 1000, 23; /定义Student类型结构体变量的同时赋以初值 Store S1, S2; /定义两个Store类对象,其中数据成员item为int类型 Store S3;/定义Store类对象S3,其中数据成员item为Student类型,Store D; /定义Store类对象D,其中数据成员item为double类型 S1.PutElem(3); /向对象S1中存入数据(初始化对象S1) S2.PutElem(-7); /向对象S2中存入数据(初始化对象S2) cout S1.GetElem() S2.GetElem() endl; /输出对象S1和S2的数据成员 S3.PutElem(g); /向对象D中存入数据(初始化对象D) cout The student id is S3.GetElem().id endl;/输出对象S3的数据成员 /D.PutElem(6.5); cout Retrieving object D ;cout D.GetElem() item2 ? item1: item2; maxitem=maxitemitem3? maxitem: item3; return maxitem;#endif/EXAMPLE9_1.CPP/主程序#include #include EXAMPLE901.H#include EXAMPLE901B.Hvoid main() Max nmyMax(1,2,3); Max dblmyMax(1.2,1.3,-1.4); coutnmyMax.GetMaxItem()endl; coutdblmyMax.GetMaxItem()ptrNext; /一般情况 return ptrTemp;/链表类构造函数,4个私有指针成员设置为空,链表初始长度设置为0,初始当前结点/初始位置为-1templateLinkedList:LinkedList(void):ptrFront(NULL),ptrTail(NULL), ptrPrev(NULL),ptrCurr(NULL),nListLength(0),nPosition(-1) /重载=号运算符templateLinkedList& LinkedList:operator=(const LinkedList& list),if(this!=,if(!ptrFront) /如果当前指针为空,链表为空直接返回 return; if(nPos=nListLength|nPosNextListNode(); ptrPrev=ptrFront; nStartPos=1; for(nPosition=nStartPos;nPosition!=nPos;nPosition+) /寻找该位置并使当前指针指向该位置, ptrPrev=ptrCurr; ptrCurr=ptrCurr-NextListNode(); /当前指针指向当前结点的后续结点templatevoid LinkedList:Next() if(ptrCurr) ptrPrev=ptrCurr; ptrCurr=ptrCurr-NextListNode(); nPosition+; /将数据为nItem的结点插入到链表头template,void LinkedList:InsertFront(const T,newListNode=GetListNode(nItem); ptrCurr-InsertAfter(newListNode); /将数据为nItem的结点插入到链表的当前位置之前templatevoid LinkedList:InsertAt(const T else /一般情况 ,newListNode=GetListNode(nItem); ptrPrev-InsertAfter(newListNode); if(ptrPrev=ptrTail) ptrTail=newListNode; nPosition=nListLength; ptrCurr=newListNode; /将数据为nItem的结点插入到链表当前结点之后templatevoid LinkedList:InsertAfter(const T if(!ptrCurr) /处理空链表的情况 ,newListNode=GetListNode(nItem); ptrCurr=newListNode; ptrFront=ptrCurr; else /一般情况 newListNode=GetListNode(nItem); ptrCurr-InsertAfter(newListNode); if(ptrPrev=ptrTail) ptrTail=newListNode; nPosition=nListLength; ptrCurr=newListNode; nListLength+;/删除链表中的当前结点templatevoid LinkedList:DeleteCurr(), ListNode *ptr; if(!ptrCurr) /处理空链表的情况 cerrNextListNode(); else /一般情况 ptr=ptrPrev-DeleteAfter(); if(ptr=ptrTail) ptrTail=ptrPrev; nPosition-; ptrCurr=ptr-NextListNode(); FreeListNode(ptr);,nListLength-;/删除链表中所有结点并释放资源templatevoid LinkedList:DeleteAll() ListNode *ptrCurrPos, *ptrNextPos; ptrCurrPos=ptrFront; while(ptrCurrPos) /循环处理删除链表中的各个结点 ptrNextPos=ptrCurrPos-NextListNode(); FreeListNode(ptrCurrPos); ptrCurrPos=ptrNextPos; ptrFront=NULL; ptrTail=NULL; ptrPrev=NULL; ptrCurr=NULL;,nListLength=0; nPosition=-1;/删除链表的头结点templateint LinkedList:DeleteHead() ListNode *ptr=ptrFront; if(ptrFront) ptrFront=ptrFront-NextListNode(); delete ptr; nListLength-; return 1; else /处理链表为空的情况 coutThe List is empty!ShowDate(); ptr=ptr-NextListNode(); if(nPosition=-1) /list为空 return; ptrPrev=NULL; ptrCurr=ptrFront; for(int nPos=0;nPos!=list.CurrPosition();nPos+) /将新链表的各个数据成员设置与原链表相同 ptrPrev=ptrCurr; ptrCurr=ptrCurr-NextListNode(); nPosition=nPos; nListLength=list.ListLength();,/获得下一个新结点,返回新结点地址templateListNode *LinkedList:GetListNode(const T,ptrCurr=ptrCurr-NextListNode(); /在链表中查找数据templateint LinkedList:Find(T/删除链表中满足条件的结点template,void LinkedList:Delete(T key) ptrCurr=ptrFront; ptrPrev=NULL; if(!ptrCurr) return; while(ptrCurr /在排序链表中插入新结点构成新的排序链表,templatevoid LinkedList:InsertOrder(T nItem) ListNode *newListNode, *next

温馨提示

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

最新文档

评论

0/150

提交评论