面向對象的程序設計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

提交評論