C 面向?qū)ο蟪绦蛟O(shè)計(jì) 課件 第6章 模板_第1頁(yè)
C 面向?qū)ο蟪绦蛟O(shè)計(jì) 課件 第6章 模板_第2頁(yè)
C 面向?qū)ο蟪绦蛟O(shè)計(jì) 課件 第6章 模板_第3頁(yè)
C 面向?qū)ο蟪绦蛟O(shè)計(jì) 課件 第6章 模板_第4頁(yè)
C 面向?qū)ο蟪绦蛟O(shè)計(jì) 課件 第6章 模板_第5頁(yè)
已閱讀5頁(yè),還剩25頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第6章模板 本章主要內(nèi)容:6.1函數(shù)模板

6.2類模板

6.3類模板與靜態(tài)成員

6.4*類模板與友元

6.5*繼續(xù)前行

計(jì)算機(jī)學(xué)院李衛(wèi)明

C++提供了模板機(jī)制,通過(guò)模板可以建立具有通用類型的函數(shù)庫(kù)或類庫(kù),為一系列邏輯功能相同而數(shù)據(jù)類型不同的函數(shù)或類創(chuàng)建框架。模板可使程序可以處理在編程時(shí)未知類型的對(duì)象,對(duì)象的類型在使用時(shí)才確定。模板提供的多態(tài)是一種參數(shù)化多態(tài),是編譯時(shí)多態(tài)。模板提供了一種重用程序源代碼的有效方法,是STL泛型編程基礎(chǔ)。模板是對(duì)具有相同特性的函數(shù)或類的再抽象,它的本質(zhì)就是將所處理的數(shù)據(jù)類型說(shuō)明為參數(shù),這樣可使一段程序代碼能用于處理多種不同類型的數(shù)據(jù),提高了代碼的可重用性。

函數(shù)抽象成函數(shù)模板,類抽象成類模板,函數(shù)模板產(chǎn)生實(shí)例函數(shù),也稱模板函數(shù),類模板產(chǎn)生實(shí)例類,也稱為模板類。計(jì)算機(jī)學(xué)院李衛(wèi)明6.1 函數(shù)模板

6.1.1 函數(shù)模板與模板函數(shù)

下列重載函數(shù)分別返回兩個(gè)整型數(shù)、兩個(gè)雙精度實(shí)型數(shù)以及兩個(gè)字符串對(duì)象中大的對(duì)象引用:constint&Max(constint&a,constint&b);constdouble&Max(constdouble&a,constdouble&b);conststring&Max(conststring&a,conststring&b);這些函數(shù)代碼實(shí)現(xiàn)了三個(gè)處理不同類型的數(shù)據(jù)最大值函數(shù)的重載(函數(shù)定義在下頁(yè)),名字都叫Max,程序代碼中實(shí)際調(diào)用時(shí),編譯器可根據(jù)實(shí)參類型確定調(diào)用的某個(gè)具體函數(shù),如下面語(yǔ)句段中:

strings1(strCity1),s2(strCity2);cout<<Max(3,5)<<endl;//調(diào)用第一個(gè)Max函數(shù)

cout<<Max(3.8,2.5)<<endl;//調(diào)用第二個(gè)Max函數(shù)

cout<<Max(s1,s2)<<endl;//調(diào)用第三個(gè)Max函數(shù)計(jì)算機(jī)學(xué)院李衛(wèi)明constint&Max(constint&a,constint&b){if(a>b)returna;elsereturnb;}constdouble&Max(constdouble&a,constdouble&b){if(a>b)returna;elsereturnb;}conststring&Max(conststring&a,conststring&b){if(a>b)returna;elsereturnb;}計(jì)算機(jī)學(xué)院李衛(wèi)明上述函數(shù)重載為程序可讀性帶來(lái)了便利。同時(shí),上述三個(gè)Max函數(shù)代碼的處理邏輯相同,只是所處理數(shù)據(jù)的類型不同,存在很大程度上的重復(fù),而且,這樣定義的三個(gè)函數(shù)不適合返回未確定類型對(duì)象的最大值:如將來(lái)我們?cè)O(shè)計(jì)了蘋果類,并且定義了以蘋果直徑比較蘋果大小的方法,我們還得為返回大蘋果對(duì)象定義相應(yīng)的Max函數(shù)。C++為我們提供了函數(shù)模板(functiontemplate)機(jī)制解決這一需求。具體就是對(duì)處理邏輯相同、只是所處理數(shù)據(jù)類型不同的函數(shù),將其中類型參數(shù)化,抽象成函數(shù)模板,再由編譯器通過(guò)函數(shù)模板產(chǎn)生模板函數(shù)(templatefunction)。正如函數(shù)調(diào)用前必須有函數(shù)聲明或函數(shù)定義一樣,調(diào)用模板函數(shù)前,必須先有函數(shù)模板聲明或函數(shù)模板定義。函數(shù)模板聲明的一般格式如下:template<typename類型參數(shù)名>返回值類型函數(shù)模板名(形參表);或template<typename類型參數(shù)名1,typename類型參數(shù)名2,…>返回值類型函數(shù)模板名(形參表);兩個(gè)T類型對(duì)象間求大的對(duì)象的Max函數(shù)模板聲明如下:template<typenameT>constT&Max(constT&a,constT&b);計(jì)算機(jī)學(xué)院李衛(wèi)明函數(shù)模板定義的一般格式如下:template<typename類型參數(shù)名>返回值類型函數(shù)模板名(形參表){ ……//函數(shù)模板體}或template<typename類型參數(shù)名1,typename類型參數(shù)名2,…>返回值類型函數(shù)模板名(形參表){ ……//函數(shù)模板體}計(jì)算機(jī)學(xué)院李衛(wèi)明Max函數(shù)模板定義如下:template<typenameT>constT&Max(constT&a,constT&b){if(a>b)returna;elsereturnb;}函數(shù)模板是對(duì)函數(shù)的抽象,描述的是使用類型參數(shù)來(lái)產(chǎn)生一組函數(shù)的模板,它不是某一個(gè)具體的函數(shù)。使用函數(shù)模板時(shí),編譯器可根據(jù)需要,將函數(shù)模板內(nèi)的所有類型參數(shù)取某一個(gè)具體的數(shù)據(jù)類型后生成具體的函數(shù)代碼,生成的函數(shù)稱為模板函數(shù),在程序中真正執(zhí)行的代碼是模板函數(shù)的代碼。計(jì)算機(jī)學(xué)院李衛(wèi)明下述兩種在表達(dá)式中使用函數(shù)模板的方式都可讓編譯器生成并調(diào)用該模板函數(shù):函數(shù)模板名(實(shí)參表)或函數(shù)模板名<類型1,類型2,…>(實(shí)參表)第一種使用方式,編譯器將根據(jù)實(shí)參類型推斷出函數(shù)模板中類型形式參數(shù)對(duì)應(yīng)的具體類型,第二種方式中,<類型1,類型2,…>稱為類型實(shí)參表,編譯器無(wú)需推導(dǎo),用類型實(shí)參表中的類型來(lái)確定類型形式參數(shù)對(duì)應(yīng)的具體類型。編譯器確定類型形式參數(shù)對(duì)應(yīng)的具體類型,生成模板函數(shù)并調(diào)用,這一工作在編譯階段完成。

如果編譯器無(wú)法根據(jù)實(shí)參推斷出函數(shù)模板中類型形式參數(shù)對(duì)應(yīng)的具體類型、存在多種推斷方案或者類型實(shí)參表提供的類型不符合函數(shù)模板要求,編譯器將報(bào)錯(cuò)。計(jì)算機(jī)學(xué)院李衛(wèi)明下列語(yǔ)句是函數(shù)模板Max的使用示例。

charstrCity1[]="BeiJing";charstrCity2[]="ShangHai";strings1(strCity1),s2(strCity2);cout<<Max(3,5)<<endl;//推斷T為intcout<<Max(3.8,2.5)<<endl;//推斷T為doublecout<<Max(s1,s2)<<endl;//推斷T為stringcout<<Max<string>("BeiJing","ShangHai")<<endl;//指定T為stringcout<<Max("HangZhou","ShangHai")<<endl;

下列語(yǔ)句因編譯器無(wú)法推斷出參數(shù)類型,將報(bào)錯(cuò)://實(shí)參類型分別是constchar[8]constchar[9]//錯(cuò)誤:cout<<Max("BeiJing","ShangHai")<<endl;//實(shí)參類型分別是char[8]char[9]//錯(cuò)誤:cout<<Max(strCity1,strCity2)<<endl;計(jì)算機(jī)學(xué)院李衛(wèi)明函數(shù)模板Max中類型參數(shù)T必須符合可進(jìn)行<比較的要求,Max不可用于不能進(jìn)行<比較的2個(gè)對(duì)象。如將來(lái)我們?cè)O(shè)計(jì)了蘋果類,定義了以蘋果直徑比較蘋果大小的方法,我們就可以對(duì)2個(gè)蘋果對(duì)象使用Max函數(shù)模板,返回大的一個(gè)蘋果,Max函數(shù)模板達(dá)到了適用于函數(shù)模板設(shè)計(jì)時(shí)還未知新類型的目的。參數(shù)類型推斷一般根據(jù)實(shí)參類型直接進(jìn)行,很少進(jìn)行類型轉(zhuǎn)換,如果編譯器不能推斷出類型或存在多種推斷時(shí),編譯器會(huì)報(bào)錯(cuò),一般可根據(jù)編譯器錯(cuò)誤提示查找解決辦法。模板函數(shù)類似于重載函數(shù),但是同一個(gè)函數(shù)模板類型形式參數(shù)具體化(實(shí)例化)后的所有模板函數(shù)必須執(zhí)行相同的代碼,而函數(shù)重載時(shí)在每個(gè)函數(shù)體中可以執(zhí)行不同的代碼,當(dāng)遇到執(zhí)行的代碼有所不同時(shí),不能簡(jiǎn)單地套用函數(shù)模板,而應(yīng)像重載普通函數(shù)那樣進(jìn)行重載。與普通函數(shù)聲明位于頭文件,函數(shù)定義位于.cpp文件不同,一般編譯器要求函數(shù)模板的定義也位于頭文件中或使用函數(shù)模板的源程序文件內(nèi)。計(jì)算機(jī)學(xué)院李衛(wèi)明6.1.2 內(nèi)聯(lián)函數(shù)模板

對(duì)于頻繁調(diào)用的簡(jiǎn)單函數(shù),使用內(nèi)聯(lián)函數(shù)可提高程序的執(zhí)行效率。使用內(nèi)聯(lián)函數(shù)模板同樣可提高程序的執(zhí)行效率。使用內(nèi)聯(lián)函數(shù)模板,只需在函數(shù)模板聲明和函數(shù)模板定義前加入inline即可,函數(shù)模板使用不變。如:template<typenameT>inlineconstT&Max(constT&a,constT&b);Max函數(shù)模板定義如下:template<typenameT>inlineconstT&Max(constT&a,constT&b){if(a>b)returna;elsereturnb;}計(jì)算機(jī)學(xué)院李衛(wèi)明6.1.3 函數(shù)模板重載函數(shù)模板也可以重載。如:template<typenameT>constT&Max(constT&a,constT&b);//2個(gè)中找出最大template<typenameT>constT&Max(constT&a,constT&b,constT&c);//3個(gè)中找出最大template<typenameT>constT&Max(constTA[],intiCount);//iCount個(gè)元素?cái)?shù)組中找出最大template<typenameT>constT&Max(constTA[],intiCount){intm=0;for(inti=1;i<iCount;++i)if(A[i]>A[m])m=i;returnA[m];}//其它函數(shù)模板定義省略計(jì)算機(jī)學(xué)院李衛(wèi)明程序中遇到如下使用函數(shù)模板的代碼段時(shí),編譯器分別根據(jù)函數(shù)模板使用時(shí)實(shí)參類型和個(gè)數(shù),從不同的函數(shù)模板推斷出類型參數(shù)的實(shí)際類型后生成模板函數(shù)代碼再進(jìn)行調(diào)用。

intA[]={1,3,5,7,9};cout<<Max(6,5)<<endl;cout<<Max(3,5,8)<<endl;cout<<Max(A,5)<<endl;計(jì)算機(jī)學(xué)院李衛(wèi)明6.1.4 函數(shù)模板和函數(shù)constchar*Max(constchar*a,constchar*b){if(strcmp(a,b)>=0)returna;elsereturnb;}//2個(gè)中找出最大template<typenameT>constT&Max(constT&a,constT&b){if(a>b)returna;elsereturnb;}計(jì)算機(jī)學(xué)院李衛(wèi)明C++容許定義同名的函數(shù)模板和函數(shù)。重載函數(shù)模板和函數(shù)后,編譯器首先匹配類型完全相同的函數(shù),如果匹配失敗,再尋求函數(shù)模板進(jìn)行匹配。

重載Max函數(shù)模板和Max函數(shù)后,下述語(yǔ)句可以輸出正確結(jié)果。

charstrCity1[]="BeiJing";charstrCity2[]="ShangHai";strings1(strCity1),s2(strCity2);cout<<Max(s1,s2)<<endl;//調(diào)用模板函數(shù)

cout<<Max<string>("BeiJing","ShangHai")<<endl;//調(diào)用模板函數(shù)

cout<<Max("HangZhou","ShangHai")<<endl;//調(diào)用函數(shù)

cout<<Max("BeiJing","ShangHai")<<endl;//調(diào)用函數(shù)

cout<<Max(strCity1,strCity2)<<endl;//調(diào)用函數(shù)C++還具有函數(shù)模板特化和部分特化機(jī)制,在此不再展開(kāi)。計(jì)算機(jī)學(xué)院李衛(wèi)明6.2 類模板

6.2.1 類模板與模板類前面學(xué)習(xí)了如何設(shè)計(jì)和使用類,例如,我們需要整形棧時(shí),我們?cè)O(shè)計(jì)實(shí)現(xiàn)了整形棧類,然后,利用整形棧類建立整形棧對(duì)象,解決實(shí)際問(wèn)題。假如程序設(shè)計(jì)中我們還需要用棧來(lái)保存字符串對(duì)象,我們需要再設(shè)計(jì)實(shí)現(xiàn)字符串棧類,而整形棧類和字符串棧類的功能相同,實(shí)現(xiàn)的方法也相同,只是處理的數(shù)據(jù)類型不同,這樣的代碼存在很大程度上的重復(fù),而且,將來(lái)如果需要設(shè)計(jì)實(shí)現(xiàn)了蘋果類,我們需要在棧中保存蘋果時(shí)還是需要設(shè)計(jì)實(shí)現(xiàn)蘋果棧類。與函數(shù)模板類似,C++支持類模板(classtemplate)。上述情形下,我們只需要將棧類中保存的元素類型參數(shù)化后,抽象成棧類模板即可,需要時(shí),再由編譯器根據(jù)棧類模板自動(dòng)生成具體棧類的代碼,棧類就是棧類模板的實(shí)例,再通過(guò)棧類模板生成的棧類建立棧對(duì)象,滿足實(shí)際需求,根據(jù)類模板自動(dòng)生成的實(shí)例類稱為模板類(templateclass)。類模板是類的抽象,模板類是類模板綁定模板參數(shù)后形成的實(shí)例。C++STL正是以類模板形式提供各種容器或容器適配器,大大提高了代碼的通用性,對(duì)效率絲毫沒(méi)有影響。我們?cè)诘诙聵永惺褂玫恼穷惸0褰壎0鍏?shù)后生成的模板類,如整形棧正是STLstack類模板綁定整形參數(shù)后編譯器生成的整形棧模板類,字符串鏈表正是STLlist類模板綁定string類型參數(shù)后編譯器生成的字符串鏈表模板類。計(jì)算機(jī)學(xué)院李衛(wèi)明6.2.2 類模板定義和成員函數(shù)實(shí)現(xiàn)類模板是參數(shù)化的類。類模板定義與類的定義類似,只是以關(guān)鍵字template開(kāi)始,尖括號(hào)里含類型參數(shù),一般形式如下:template<typename類型參數(shù)名>class類模板名{……//類模板體};或template<typename類型參數(shù)名1,typename類型參數(shù)名2,…>class類模板名{……//類模板體};類模板聲明和實(shí)現(xiàn)中,關(guān)鍵字typename可以用關(guān)鍵字class代替,效果相同。參數(shù)類型可以用于定義數(shù)據(jù)成員的類型、函數(shù)成員的參數(shù)和返回值類型,還可用于定義類模板內(nèi)的類型成員。計(jì)算機(jī)學(xué)院李衛(wèi)明與類的成員函數(shù)定義相同,類模板的成員函數(shù)不但可以在類模板內(nèi)定義,也可以在類模板外定義。在類模板外定義時(shí),需要采用下面的形式:template<typename類型參數(shù)名>返回值類型類模板名<類型參數(shù)名>::成員函數(shù)名(形參表){ ……//函數(shù)體}或template<typename類型參數(shù)名1,typename類型參數(shù)名2,…>返回值類型類模板名<類型參數(shù)名1,類型參數(shù)名2,…>::成員函數(shù)名(形參表){ ……//函數(shù)體}計(jì)算機(jī)學(xué)院李衛(wèi)明由類模板產(chǎn)生模板類的形式如下:類模板名<類型>或類模板名<類型1,類型2,…>此處實(shí)際類型必須由程序員指明,不能由編譯器推斷。編譯器據(jù)此生成一個(gè)具體的模板類,然后使用模板類建立和使用具體對(duì)象。生成一個(gè)具體的模板類工作在編譯階段完成。

EX6.1是一個(gè)實(shí)現(xiàn)了動(dòng)態(tài)數(shù)組功能的Array類模板的簡(jiǎn)單實(shí)例。程序中先定義了Array動(dòng)態(tài)數(shù)組類模板,實(shí)現(xiàn)了類模板中成員函數(shù)(成員運(yùn)算符),在主程序中,建立了可存放n個(gè)整數(shù)的整形動(dòng)態(tài)數(shù)組模板類對(duì)象obj,再進(jìn)行了存取、輸出,又建立了可存放n個(gè)字符串的字符串動(dòng)態(tài)數(shù)組模板類對(duì)象strObj,其中每個(gè)字符串對(duì)象缺省構(gòu)造為空字符串,再對(duì)數(shù)組對(duì)象進(jìn)行了存取、輸出;程序執(zhí)行完畢后,2個(gè)動(dòng)態(tài)數(shù)組對(duì)象進(jìn)行析構(gòu),包含其中所有字符串對(duì)象的析構(gòu),不會(huì)造成任何內(nèi)存泄漏。樣例程序中進(jìn)行了下標(biāo)合法性判斷,如果下標(biāo)越界,會(huì)拋出異常,關(guān)于異常,詳見(jiàn)下一章。具體代碼見(jiàn)Ex6.1。計(jì)算機(jī)學(xué)院李衛(wèi)明6.2.3 內(nèi)聯(lián)成員函數(shù)、非類型參數(shù)、函數(shù)調(diào)用運(yùn)算符重載與類聲明(定義)內(nèi)實(shí)現(xiàn)的成員函數(shù)是內(nèi)聯(lián)成員函數(shù)一樣,直接在類模板定義里實(shí)現(xiàn)的成員函數(shù)也是內(nèi)聯(lián)成員函數(shù)。如果在類模板定義內(nèi)的成員函數(shù)聲明前面帶有inline關(guān)鍵字說(shuō)明,這樣的成員函數(shù)也是內(nèi)聯(lián)成員函數(shù)。本章后續(xù)棧類模板樣例中的入棧、出棧等函數(shù)聲明前面帶有inline關(guān)鍵字的成員函數(shù)都是內(nèi)聯(lián)成員函數(shù)。在模板的類型形參表中不但可以包含常規(guī)類型參數(shù),還可以包含非類型參數(shù)。非類型參數(shù)表示一個(gè)值,而不是一個(gè)類型。我們通過(guò)一個(gè)類型名而非關(guān)鍵字typename或class指定非類型參數(shù)。當(dāng)模板實(shí)例化時(shí),非類型參數(shù)被一個(gè)常量值所代替,這個(gè)常量值可以被模板用戶提供或編譯器推導(dǎo)出來(lái)。本節(jié)數(shù)組類模板樣例Ex6.2中MaxSIZE正是這樣的非類型參數(shù),數(shù)組Array類模板實(shí)例化時(shí)由用戶提供的值為6的常量n代替,代表模板類的數(shù)組容器可以存放6個(gè)元素。C++STL應(yīng)用中經(jīng)常用到函數(shù)對(duì)象,作為算法的實(shí)參。所謂函數(shù)對(duì)象實(shí)際就是重載了函數(shù)調(diào)用運(yùn)算符()的類的實(shí)例,這樣的對(duì)象可以象普通函數(shù)一樣使用,STL中也稱為仿函數(shù)。用戶自定義對(duì)象通過(guò)運(yùn)算符()調(diào)用函數(shù),C++規(guī)定函數(shù)調(diào)用運(yùn)算符()只能重載為類的成員函數(shù),具體聲明格式如下:返回值類型operator()(形參表);在C++中,由于上面聲明格式中形參表的參數(shù)個(gè)數(shù)可以是不確定的,因此,函數(shù)調(diào)用運(yùn)算符()是不確定目數(shù)運(yùn)算符。

具體代碼見(jiàn)Ex6.2。計(jì)算機(jī)學(xué)院李衛(wèi)明6.2.4 類模板名簡(jiǎn)化表示模板類類模板是生成模板類的藍(lán)圖,不是一個(gè)類型;類模板綁定模板參數(shù)后形成的類模板實(shí)例,也就是模板類,才是一個(gè)類型。模板類可以出現(xiàn)在程序中需要類型的位置,類模板名則不可以。這一規(guī)則有一個(gè)例外,就是在本類模板作用域中,模板類可以簡(jiǎn)化為類模板名,省略類模板的模板參數(shù)綁定;在類模板作用域外,模板類不可以簡(jiǎn)化為類模板名,必須綁定模板參數(shù)。

本章后面樣例Ex6.3和Ex6.4中CStack類模板,在類模板定義和類模板成員函數(shù)定義中,也就是CStack類模板作用域中,需要類型的位置可以用類模板名簡(jiǎn)化表示,如Ex6.3中語(yǔ)句:

CStack(constCStack&rhs);//拷貝構(gòu)造函數(shù)

CStack&operator=(constCStack&rhs);//賦值運(yùn)算符重載是下面2個(gè)語(yǔ)句的簡(jiǎn)化表示:

CStack<T>(constCStack<T>&rhs);//拷貝構(gòu)造函數(shù)

CStack<T>&operator=(constCStack<T>&rhs);//賦值運(yùn)算符重載類模板作用域外,也就是界定符::前不可以用類模板名簡(jiǎn)化表示模板類。具體參見(jiàn)后面樣例代碼Ex6.3、Ex6.4。計(jì)算機(jī)學(xué)院李衛(wèi)明6.2.5 典型范例——鏈棧類模板設(shè)計(jì)和實(shí)現(xiàn)

Ex6.3在第2章2.6節(jié)單鏈表表示的整形棧基礎(chǔ)上,又增加了拷貝控制函數(shù)后進(jìn)一步抽象成鏈棧類模板,并在此基礎(chǔ)上增加了類模板的友元函數(shù)Dump,用于將棧內(nèi)元素倒出并顯示,展示了類模板友元函數(shù)的用法。語(yǔ)句5~9和語(yǔ)句36是有關(guān)類模板的友元函數(shù)聲明,詳細(xì)解釋在下一節(jié)。本樣例中采用指令方式測(cè)試類模板,Parse函數(shù)模板的不同實(shí)例負(fù)責(zé)整形指令和字符串指令的解釋。輸入描述開(kāi)始int或string代表需要處理的對(duì)象類型。對(duì)于每種類型,先構(gòu)造兩個(gè)目標(biāo)類型的空棧S1、S2,讀入整數(shù)n,再讀入n對(duì)指令v、x;1<=v<=2;將元素x入第v個(gè)棧,n對(duì)指令處理完成后,通過(guò)拷貝構(gòu)造和賦值、移動(dòng)構(gòu)造和移動(dòng)賦值4個(gè)函數(shù),根據(jù)S1拷貝構(gòu)造S3、S3移動(dòng)構(gòu)造S5,無(wú)參構(gòu)造空棧S4、S6,S2復(fù)制賦值給S4、S4移動(dòng)賦值給S6,最后,倒出顯示S1、S2、S5、S6四個(gè)棧中元素。輸出描述每個(gè)棧中輸出占一行,元素間以空格分隔。具體代碼見(jiàn)Ex6.3。計(jì)算機(jī)學(xué)院李衛(wèi)明6.2.6 內(nèi)嵌容器的棧類模板設(shè)計(jì)和實(shí)現(xiàn)

Ex6.4設(shè)計(jì)和實(shí)現(xiàn)的棧類模板采用參數(shù)化類型的內(nèi)嵌容器表示棧內(nèi)元素,利用容器的功能,改造接口后實(shí)現(xiàn)了棧類模板。樣例中數(shù)據(jù)成員m_cont的類型是模板的第二參數(shù),缺省是綁定棧元素同樣類型的雙端隊(duì)列,實(shí)際使用時(shí)可以采用缺省類型(語(yǔ)句105),也可以綁定字符串鏈表模板類。Parse函數(shù)模板同樣采用了多類型參數(shù)和缺省參數(shù)的方式實(shí)現(xiàn)。采用內(nèi)嵌容器作為子對(duì)象后,本樣例中棧類模板內(nèi)元素存放空間雖然最終采用了動(dòng)態(tài)分配,但類模板本身無(wú)需直接動(dòng)態(tài)分配,因而,本例中的構(gòu)造函數(shù)、拷貝控制函數(shù)(拷貝構(gòu)造、移動(dòng)構(gòu)造、復(fù)制賦值、移動(dòng)賦值、析構(gòu)函數(shù))直接由編譯器合成即可,大大簡(jiǎn)化了程序,是現(xiàn)代C++程序設(shè)計(jì)值得推薦的方式。STL中stack和queue正是利用類似的內(nèi)嵌容器功能的方法實(shí)現(xiàn)的,因而稱為容器適配器。具體代碼見(jiàn)Ex6.4。計(jì)算機(jī)學(xué)院李衛(wèi)明6.3 類模板與靜態(tài)成員類模板也可以同樣定義靜態(tài)數(shù)據(jù)成員和靜態(tài)函數(shù)成員。類模板的靜態(tài)數(shù)據(jù)成員和靜態(tài)函數(shù)成員為相同參數(shù)實(shí)例化的模板類所共享,不同參數(shù)實(shí)例化的模板類具有不同的靜態(tài)數(shù)據(jù)成員和靜態(tài)函數(shù)成員。下面程序片段中,TSample類模板定義了靜態(tài)數(shù)據(jù)成員m_iCount和靜態(tài)函數(shù)成員GetCount,完成了靜態(tài)數(shù)據(jù)成員的初始化。template<classT>classTSample{public:staticintGetCount();TSample(){++m_iCount;}private:staticintm_iCount;};計(jì)算機(jī)學(xué)院李衛(wèi)明template<classT>intTSample<T>::GetCount(){returnm_iCount;}template<classT>intTSample<T>::m_iCount=0;模板類TSample<int>和TSample<string>分別具有不同的靜態(tài)數(shù)據(jù)成員和靜態(tài)函數(shù)成員的實(shí)現(xiàn),模板類TSample<int>和TSample<string>分別建立了2個(gè)和1個(gè)實(shí)例,構(gòu)造函數(shù)中利用靜態(tài)數(shù)據(jù)成員完成實(shí)例計(jì)數(shù),添加少量代碼形成完整程序后,后面測(cè)試語(yǔ)句輸出結(jié)果分別是2和1。TSample<int>t1,t2;TSample<string>st1;cout<<TSample<int>::GetCount()<<endl;cout<<TSample<string>::GetCount()<<endl;計(jì)算機(jī)學(xué)院李衛(wèi)明6.4 *類模板與友元正如類可以具有友元函數(shù)和友元類一樣,類模板也可以具有友元函數(shù)和友元類。類模板的友元函數(shù)和友元類關(guān)系比較復(fù)雜,下面分別預(yù)以介紹。6.4.1 類模板的普通友元普通函數(shù)和普通類作為類模板的友元情況比較簡(jiǎn)單。普通函數(shù)和普通類是每個(gè)類模板的實(shí)例的友元。下面程序片段中,普通函數(shù)SomeFriendFun和普通類FC是每個(gè)類模板TSample的實(shí)例的友元,形成多個(gè)模板類共同擁有一個(gè)友元函數(shù)和友元類關(guān)系。classFC;template<classT>classTSample{public:friendclassFC;friendvoidSomeFriendFun();//省略其余成員};計(jì)算機(jī)學(xué)院李衛(wèi)明6.4.2 普通類的友元模板函數(shù)模板和類模板作為普通類的友元時(shí),每個(gè)函數(shù)模板的實(shí)例-模板函數(shù)和每個(gè)類模板的實(shí)例-模板類都是這個(gè)類的友元。下面程序片段中,函數(shù)模板TFun的每個(gè)實(shí)例和類模板TC的每個(gè)實(shí)例都是CSample類的友元,形成1個(gè)類擁有多個(gè)友元函數(shù)和友元類關(guān)系。classCSample{public:template<classT>friendclassTC;template<classT>friendvoidTFun(T);//省略其余成員};計(jì)算機(jī)學(xué)院李衛(wèi)明6.4.3 多對(duì)多關(guān)系的類模板和友元模

溫馨提示

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

評(píng)論

0/150

提交評(píng)論