《C++面向?qū)ο蟪绦蛟O(shè)計》第9章 模板_第1頁
《C++面向?qū)ο蟪绦蛟O(shè)計》第9章 模板_第2頁
《C++面向?qū)ο蟪绦蛟O(shè)計》第9章 模板_第3頁
《C++面向?qū)ο蟪绦蛟O(shè)計》第9章 模板_第4頁
《C++面向?qū)ο蟪绦蛟O(shè)計》第9章 模板_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

《C++面向?qū)ο蟪绦蛟O(shè)計》教學內(nèi)容

第1章C++概述

第2章類和對象

第3章面向?qū)ο蟪绦蛟O(shè)計概述

第4章進一步學習類和對象

第5章堆與復(fù)制構(gòu)造函數(shù)

第6章繼承性:派生類

第7章運算符重載

第8章虛函數(shù)和多態(tài)性

第9章模板

第10章類庫和C++的標準模板庫STL

第11章輸入輸出流

第12章異常處理

第9章模板

9.1模板的概念

9.2函數(shù)模板

9.3重載模板函數(shù)

9.4類模板的定義

9.5使用類模板

9.6應(yīng)用舉例

問題的引入

?很多算法本身的描述其實與其所涉及數(shù)據(jù)的類型

是無關(guān)的。

?但是,高級語言大多數(shù)都是基于類型系統(tǒng)的語言,

當用高級語言表達算法的實現(xiàn)時,就必須明確指

出其具體的數(shù)據(jù)類型,

?這樣以來就必然導(dǎo)致同一個算法有多個不同的實

現(xiàn)(針對不同的數(shù)據(jù)類型)。

?從而使工作量加大,使用麻煩,維護困難。

例:將兩個數(shù)進行交換(請同學們想一想共

有幾種方案?)

解決方案一:宏定義

?在C語言中,宏定義是解決類型無關(guān)算

法的首選解決方案。例:

#definemax(x,y)((x)>(y)?(x):(y));

?宏定義有如下的缺點:

重復(fù)計算

只能處理簡單的情況

例如:這里的Swap(x,y)使用宏定義就不好處理。

解決方案二:用C語言的函數(shù)

voidSwapl(int*x,int*y)

inttemp;

temp=*x;

*x=*y;

*y=temp;

}

voidSwapF(float*x,float*y)從上面的實現(xiàn)可以看

(出,這種方案不僅實

floattemp;現(xiàn)上浪費很大,而且

temp=*x;使用起來非常的不方

*x=*y;便(不同的函數(shù)名)。

*y=temp;

解決方案三:C++函數(shù)名重載

voidSwap(int&x,int&y)

(

inttemp;

temp=x;

x=y;

y=temp;

}

voidSwap(float&x,float&y)與C語言相比,C++

{的函數(shù)名重載讓使用者

floattemp;

temp=x;大大地得到了解放,但

x=y;實現(xiàn)者還是需進行大量

y=temp;

的重復(fù)性勞動。

解決方案四:模板

template<classT>

voidswap(T&x5T&y)

{Tt;xy-所--謂---模--板--是---一--種---是--將--類----、

t=X;|型參數(shù)化來產(chǎn)生一系列

Y函數(shù)或類的機制。

y=t;

9.1模板的概念

?模板的英文為template,又可譯作樣板。

?C++中的模板可以用來設(shè)計與數(shù)據(jù)類型無

關(guān)的通用算法。

■這樣的通用算法能夠適用不同場合下不

同的數(shù)據(jù)類型。

?通過針對不同的數(shù)據(jù)類型實例化這些模

板,可以實現(xiàn)代碼重用,從而達到提高

軟件生產(chǎn)率的目的。

模板的作用

?通過模板可以產(chǎn)生類或函數(shù)的集合,使

它們操作不同的數(shù)據(jù)類型,

?從而避免需要為每一種數(shù)據(jù)類型都編寫

一個單獨的類或函數(shù)。

什么是模板template?

9.2函數(shù)模板

template<classtype>ret_type

func_name(parameterlist)

{//bodyoffunction}

?type是函數(shù)模板所使用的數(shù)據(jù)類型的占

位符名稱,又稱為模板參數(shù)。

?將type實例化的類型稱為模板實參,用

模板實參實例化函數(shù)模板得到的函數(shù)稱

為模板函數(shù)。

函數(shù)模板的兩種實例化方式

〃顯式實例化

〃隱式實例化

#include<iostream>

usingnamespacestd;

template<classT>Tmin(Ta,Tb)

return(a<b)?a:b;

函數(shù)模板的兩種實例化方式(續(xù))

intmain()

使用整型類型int

顯式實例化。

doubledobjl=l.l,dobj2=2.2;j

charcobjl-c\cobj2='W;

inti=12,j=68;

使用double隱式

cout?min<int>(i,cobj1)?endl;實例化

cout?min(dobj1,dobj2)?endl;

cout?min<char>(cobj2,j)?endl;

return0;

使用字符類型,

char顯式實例化

實例:求絕對值的函數(shù)模板

#include<iostream>

usingnamespacestd;

template<classX>Xmyabs(Xval)

{

returnval<0?-val:val;

)

intmain()

{

cout?myabs(-lO)?'\n';//integerabs

cout?myabs(-lO.O)<<'\n';//doubleabs

cout?myabs(-lOL)?'\n';//longabs

cout?myabs(-lO.OF)?'\n';//floatabs

return0;

函數(shù)模板與函數(shù)重載

?在每個重載函數(shù)的函數(shù)體中,可以執(zhí)行不同的

行為。

?但是,函數(shù)模板的所有實例都必須執(zhí)行同樣的

行為——只有數(shù)據(jù)類型可以不同。

voidoutdata(inti)

{]這些函數(shù)不能.

cout?i;用函數(shù)模板來

}實現(xiàn)

voidoutdata(doubled)

cout?d*3.1416;

定義多個重載函數(shù)使代碼顯得冗長

//對于整數(shù)類型

intmax(inta,intb){return(a>b)?a,b;}

//對于長整數(shù)類型

longmax(longa,longb){return(a>b)?a,b;}

//對于單精度浮點數(shù)

floatmax(floata,floatb){return(a>b)?a,b;}

//對于雙精度浮點數(shù)

doublemax(doublea,doubleb)

{return(a>b)?a,b;}

模板函數(shù)的代碼更加簡潔

?如果使用函數(shù)模板就可以減少這些不必要的

重復(fù)。例如:

template<classtype>typemax(typea,typeb)

{return(a>b)?a,b;}

?可見,模板可以大大提高程序代碼的靈活

性,減少源代碼長度。從而減輕程序員的負

相。

注意

函數(shù)模板實例化時不支持數(shù)據(jù)類型的自動轉(zhuǎn)換

當用隱式方式時,下面的方式將是一種錯誤:

swap(i,c);

因為i和cl的類型不一致,無法實例化函數(shù)模

板swap(T&x,T&y)o

但是,當用顯式方式將其聲明為:

voidswap(int&,int&)后,則可以合法去調(diào)用

了。

函數(shù)模板小結(jié)

?無論操作的是什么類型的數(shù)據(jù),許多

算法在邏輯上是相同的。

?通過建立函數(shù)模板,可以不依賴于任

何數(shù)據(jù)類型來描述算法。

?函數(shù)模板定義了一套適用于各種數(shù)據(jù)

類型數(shù)據(jù)的一般操作。

?函數(shù)模板是描述通用算法的強有力的

手段。

9.3重載函數(shù)模板

//max.h

template<classTYPE>

TYPEmax(TYPEa,TYPEb)

(

return(a>b?a:b);

)

template<classTYPE>

TYPEmax(TYPEa,TYPEb,TYPEc)

(

TYPEt;

t=(a>b)?a:b;

return(t>c)?t:c;

}

注:這種重載是指參數(shù)個數(shù)不同,而不是類型不同。

實例化函數(shù)模板時自動匹配

#include“iostream.h"

#include"max.h"

intmain()

{char*maxi;

intx=10,y=20,max2;

doublea=10.3,b=21.7,c=14.5,max3;

max2=max(x,y);

max3=max(a,b,c);

maxl=max(nX¥Zn,nABCn);

cout?nThemaximumofn?x

?nandn?y?nis:n?max2?endl;

cout?nThemaximumofn?a?M,M

?b?nandn?c?nis:n?max3?endl;

cout?nThemaximumof\nXYZ\nand\nABC\nis:n?maxl?endl;

return0;

輸出結(jié)果分析

?其結(jié)果是:

Themaximumof10and20is:20

Themaximumof10.3,21.7and14.5is:21.7

ThemaximumofnXYZnand“ABCnis:ABC

為什么會出錯?如

何改正這個錯誤?

出錯的原因

?當用char*實例化函數(shù)模板max時,得到

的模板函數(shù)如下:

char*max(char*a,char*b)

(

return(a>b)?a:b;

)

它所比較的是兩個字符串存儲單元地址的大小,

而不是兩個字符串的內(nèi)容。

改正錯誤的方法

?只要用一個普通的函數(shù)進行重載就可以

了,比如:

char*max(char*a5char*b)

return(strcmp(a5b)>0?a:b);

一般的函數(shù)重載函數(shù)模板

?即用一個非函數(shù)模板重載一個同名的函

數(shù)模板。

?目的是用一般函數(shù)來完善或者彌補模板

函數(shù)所描述的問題的漏洞。

?例:用char*實例化上例就會出現(xiàn)問題。

下面兩個聲明將指同一個函數(shù)模板

Template<classTl>

T1max(Tla,Tlb)

{

return(a>b)?a:b;

Template<classT2>

T2max(T2a,T2b)

return(a>b)?a:b;

二義性錯誤

因為T1和T并不指某個具體的類型,當用:

intmax(int,int);

時,編譯器將不知道用那一個模板將其實例

化,從而產(chǎn)生二義性錯誤。

重載函數(shù)的調(diào)用次序

?尋找一個參數(shù)完全匹配的函數(shù),若找到就

調(diào)用之。

?否則,尋找一個函數(shù)模板,將其實例化產(chǎn)

生一個匹配的函數(shù),若有則調(diào)用之。

?否則,在重載函數(shù)中找有無通過類型轉(zhuǎn)換

可產(chǎn)生參數(shù)匹配的函數(shù),若有則調(diào)用之。

?若通過以上三步均沒找到,則出現(xiàn)無匹配

函數(shù)的錯誤。若在某一步上同時有多于一

個的選擇,則為二義性錯誤。

9.4類模板的定義

問題引入:

與函數(shù)模板相似,我們在設(shè)計類時也往

往會遇到由于數(shù)據(jù)類型的不同而不得不

重復(fù)地進行類的設(shè)計,而這些類的形式

是十分相象的,基于象引入函數(shù)模板同

樣的原因,C++引入了類模板機制。

例:棧類模板

通用棧解決方案一:繼承

整數(shù)棧浮點數(shù)棧用戶定義類型的棧

通用棧解決方案二:模板

constintSIZE=10;

template<classT>classstack{

Tstck[SIZE];//使用數(shù)組實現(xiàn)堆棧

inttos;//top-of-stack堆棧頂部位置

public:

stack();//constructor

voidpush(Tch);〃將數(shù)據(jù)壓入堆棧

Tpop();〃從堆棧彈出數(shù)據(jù)

);

類模板定義的一般形式

template<class模板形參表〉

class類模板名

〃類體

);

成員函數(shù)在類模板的體外實現(xiàn)

如果成員函數(shù)在類模板的體外實現(xiàn),則每

個成員函數(shù)前都必須用與聲明該類模板

一樣的方法聲明:

template<class模板形參表,

使這樣的成員函數(shù)成為一個函數(shù)模板。

成員函數(shù)在類模板的體外實現(xiàn)實例

template<classT>voidstack::push(Td)

(

if(tos=SIZE){

cout?nStackisfull\nn;

return;

}

stck[tos]=d;

tos++;

)

template<classT>Tstack::pop()

(

if(tos==0){

cout?HStackisempty\nn;

return0;//returnnullonemptystack

}

tos—;

returnstckftos];

9.5使用類模板

?類模板必須顯式實例化為模板類后才能使用,

如:

stack<int>

就產(chǎn)生一個整形的模板類。

-類模板必須顯式實例化后,才能生成對象:

模板名V類型實參表,對象名(值實參表);

stack<int>int_stack;

安全數(shù)組模板類實例

constintSIZE=10;

template<classAType>classatype{

ATypea[SIZE];

public:

atype(){

registerinti;

for(i=0;i<SIZE;i++)a[i]=i;

)

ATyp

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論