




版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1、第五章,模 板,主要內(nèi)容,模板的概念 函數(shù)模板和模板函數(shù) 類模板和模板類,5.1 模板的概念,引例: int max( int x, int y) return (xy) ? x: y; double max( double x, double y) return (xy) ? x: y; char max( char x, char y) return (xy) ? x: y; ,可以看出,這些函數(shù)版本的功能都是相同的,只是參數(shù)類型和函數(shù)返回類型不同。 那么能否為這些函數(shù)只寫出一套代碼呢?,C+解決這個問題的一個方法就是使用模板。,利用模板機制可以顯著減少冗余信息,能大幅度地節(jié)約程序代碼,進
2、一步提高面向對象程序的可重用性和可維護性 模板概念是對類屬概念的繼承與發(fā)展。,類屬,類屬是 一種參數(shù)多態(tài)的機制。 ALGOL68語言最先引入類屬(genericity)的概念,最主要的類屬形式是類型參數(shù)化,即用一個或多個類型去參數(shù)化一個軟件元素。 基本思想: 在實際工作中人們經(jīng)常用到剛才那樣一些程序模塊,從它們的邏輯功能(或實現(xiàn)算法)看,彼此是相同的,所不同的主要是處理對象(數(shù)據(jù))的類型。 如果提供具有相同邏輯功能的程序正文(保存共性),然后把數(shù)據(jù)類型作為參數(shù)傳遞(指出不同特性),則可節(jié)約大量程序代碼,這就是類屬機制的思想,又稱為參數(shù)化模板。,類屬又可分為無約束類屬機制和約束類屬機制 無約束類
3、屬機制是指對作為類屬參數(shù)的數(shù)據(jù)類型沒有任何特殊要求 約束類屬機制則意味著對類屬參數(shù)有明確要求,只有在類屬實參滿足一定條件時才有意義。 1. 無約束類屬的例子 void swap(T ,2. 約束類屬的例子 T minimum(T x,T y) if(x=y) return x; else return y; 并不是任何數(shù)據(jù)類型都可以作為這個函數(shù)的類屬實參,只有滿足一定條件(即定義了“=”操作)的數(shù)據(jù)類型,才能作為這個函數(shù)的類屬實參。 /結構變量的比較運算與整型變量的比較運算就有很大差別 C+語言使用模板來實現(xiàn)類屬機制。,在C+中,模板是實現(xiàn)代碼重用機制的一種工具,它可以實現(xiàn)類型參數(shù)化,即把類型
4、定義為參數(shù),從而實現(xiàn)代碼的可重用性。 C+程序由類和函數(shù)組成,C+中的模板也分為類模板和函數(shù)模板。 例: T max( T x, T y) return (xy) ? x : y; ,1. 模板的概念,這個以參數(shù)化表示的函數(shù)稱為函數(shù)模板。,所謂函數(shù)模板,實際上是建立一個通用函數(shù),其函數(shù)類型和形參類型不具體指定,用一個虛擬的類型(如:T)來代替,這個通用函數(shù)就稱為函數(shù)模板。 3. 模板函數(shù) 在定義了一個函數(shù)模板后,當編譯系統(tǒng)發(fā)現(xiàn)有一個對應的函數(shù)調用時,將根據(jù)實參中的類型來確認是否匹配函數(shù)模板中對應的形參,然后生成一個重載函數(shù),該函數(shù)的定義與函數(shù)模板的函數(shù)定義體相同,稱之為模板函數(shù)。,2. 函數(shù)模
5、板,比較:函數(shù)模板和模板函數(shù)的區(qū)別,函數(shù)模板是模板的定義,定義中用到通用類型參數(shù)。 模板函數(shù)是實實在在的函數(shù)定義,它由編譯系統(tǒng)在遇到具體函數(shù)調用時所生成,具有程序代碼。,同樣,類模板是模板的定義,不是一個實實在在的類,其定義也用到通用類型參數(shù)。在定義了一個類模板后,可以創(chuàng)建類模板的實例,即生成模板類。,4. 模板、模板函數(shù)、模板類和對象之間的關系,說明:,由于模板的作用是使程序能夠對不同類型的數(shù)據(jù)進行相同方式的處理,因此,在進行相同方式的處理時,只有當參加運行的數(shù)據(jù)類型不同時,才可以定義模板。,5.2 函數(shù)模板和模板函數(shù),函數(shù)模板的定義和模板函數(shù)的生成 1) 定義函數(shù)模板的一般形式: temp
6、late 函數(shù)返回值類型 函數(shù)名(形參表) /函數(shù)體 ,例:將求最大值的函數(shù)max()定義成函數(shù)模板。,template /模板聲明 T max(T x, T y) /模板定義體 return (xy) ? x:y; 其中,T是模板形參,它既可以取系統(tǒng)預定義的數(shù)據(jù)類型,也可以取用戶自定義的類型。,2) 模板函數(shù)的生成:,定義了函數(shù)模板后,程序中并沒有得到真正的函數(shù)代碼。只有用一個具體的數(shù)據(jù)類型來代替上面的類型參數(shù)T以后,即將模板具體化后,系統(tǒng)才會生成特定于具體數(shù)據(jù)類型的程序代碼(模板函數(shù))。,當程序中有如下語句時, int i; i=max(2, 30); 編譯系統(tǒng)就會自動生成具有整型參數(shù)和返
7、回值的函數(shù)代碼: int max( int x, int y) return (xy) ? x: y; 然后將它插入到程序中,這個生成的函數(shù)稱為模板函數(shù)。這樣,如果再有一句對整型參數(shù)的函數(shù)調用,系統(tǒng)就不會再次生成函數(shù)代碼,而是直接使用已經(jīng)生成的函數(shù)代碼了。,例:,同樣,如果程序中又有了這么一句函數(shù)調用: double x=max(12.3,48.5); 編譯系統(tǒng)會先看有沒有已經(jīng)從模板生成了函數(shù)代碼,如果沒有,就生成具有雙精度浮點型參數(shù)的函數(shù)代碼: double max(double x , double y) return (xy)?x:y; ,說明:,一般來說,當編譯程序看到對模板函數(shù)的調用
8、語句時,就會根據(jù)函數(shù)模板生成對應于該特定數(shù)據(jù)類型的具體函數(shù)代碼。 但是,也可以通過聲明函數(shù)原型來告訴編譯程序實例化函數(shù)模板。例如: float max(float,float); 當編譯器看到函數(shù)原型時,會先根據(jù)函數(shù)模板生成相應的函數(shù)代碼。,例:見下例exec11.1。,例exec11-1 不同數(shù)據(jù)類型數(shù)組中的元素求和,#include using namespace std; template T Sum(T *array,int size=0) T total=0; for (int i=0;isize;i+) total+=arrayi; return total; int main()
9、 int int_array=1,3,5,7,9,11,13,15,17,19; double double_array=1.1,2.2,3.3,4.4,5.5,6.6,5.7,8.8,9.9,10.01; coutThe summary of integer array are Sum(int_array,10)endl; coutThe summary of double array are Sum(double_array,10)endl; return 0; ,在程序中,生成了兩個模板函數(shù): Sum(int_array,10)用實參int_array將類型參數(shù)T進行了實例化,int_a
10、rray為一整型數(shù)組名,編譯程序生成一個形如int Sum(int *array,int size)的模板函數(shù); Sum(double_array,10)用實參double_array將類型參數(shù)T進行了實例化,double_array為一雙精度型數(shù)組名,編譯程序生成一個形如double Sum(double *array,int size)的模板函數(shù)。,2. 函數(shù)模板的使用,雖然函數(shù)模板中的模板形參T可以實例化為各種類型,但實例化T時,虛實參之間必須保持完全一致的類型。模板類型并不具有隱式的類型轉換,例如在int與char之間、float與int之間、float與double之間等的隱式類型轉
11、換。 例: 見例exec11.2。,#include using namespace std; template T max(T a,T b) T c; if (ab) c=a; else c=b; return c; int main() int i1=50,i2=40; char c1=A,c2=B; double x1=45.6,x2=2.5e2; coutmax(i1,i2)endl; coutmax(c1,c2)endl; coutmax(x1,x2)endl; coutmax(i1,c1)endl; coutmax(i1,x1)endl; coutmax(c1,x1)endl; r
12、eturn 0; ,分析: 由于這3條語句的實參的類型與形參不一致,而max模板參數(shù)T的各實參之間必須保持一致的類型,因此出現(xiàn)編譯錯誤。 例如,max(i1,c1) 系統(tǒng)找不到與max(int, char)相匹配的函數(shù)定義。,解決方法:,采用強制類型轉換。 例:將調用語句max(i1, c1)改寫為 max(i1, int(c1) 顯式給出模板實參,強制生成對特定實例的調用。具體地說,就是在調用格式中要插入一個模板實參表。 例: cout(i1,x1)就是模板實參表,通過它通知編譯系統(tǒng)生成對形如int max(int a, int b)的函數(shù)實例的調用。這樣,在調用過程中,double型的參數(shù)
13、x1將被自動轉換成int型。,例:采用上面兩種方法對例exec11.2進行修改。, int main() int i1=50,i2=40; char c1=A,c2=B; double x1=45.6,x2=2.5e2; cout(i1,x1)(c1,x1)endl; /正確 return 0; ,問題: 比較兩個字符串哪個大,能不能用上面的函數(shù)模板直接比較兩個字符指針的大小?,分析: 比較兩個字符指針的大小不能使用上述的方法(因為:s1,s2是指針),而需要用strcmp()函數(shù)來進行。因此,需要重新定義max()來比較兩個字符串。 那么怎樣利用函數(shù)模板來實現(xiàn)這一目的呢?,max(s1,s2
14、),解決方法: 允許函數(shù)模板參與重載,即允許用普通函數(shù)重載一個同名的函數(shù)模板。 有以下兩種重載方式: 與函數(shù)模板共享函數(shù)體; 重新定義函數(shù)體。,與函數(shù)模板共享函數(shù)體,通過借用函數(shù)模板的函數(shù)體來定義重載函數(shù)模板的非模板函數(shù)。 例: template T max(T a,T b) T c; if (ab) c=a; else c=b; return c; int max(int, int); /與函數(shù)模板共享函數(shù)體,void f(int i,char c) int x; x=max(i,i); x=max(c,c); x= max(i,c);/調用int max(int,int); x=max(c
15、,i); /調用int max(int,int); 因為普通函數(shù)具有隱式類型轉換能力,所以不出錯!,重新定義函數(shù)體,在定義重載函數(shù)模板的非模板函數(shù)時,給出這個重載的非模板函數(shù)的函數(shù)體。 例: 見例exec11.4。 說明: 編譯程序在處理這種情況時, 首先尋找參數(shù)完全匹配的普通函數(shù); 然后再尋求參數(shù)完全匹配的函數(shù)模板; 最后尋求低一級的對函數(shù)的重載方法(類型轉換達到匹配)。,char * max(char *a,char *b) if (strcmp(a,b)0) return a; else return b; ,函數(shù)模板總結,函數(shù)模板是對一組函數(shù)的描述,它不是一個實實在在的函數(shù),編譯系統(tǒng)并
16、不產(chǎn)生任何執(zhí)行代碼。 當編譯系統(tǒng)在程序中發(fā)現(xiàn)有與函數(shù)模板中相匹配的函數(shù)調用時,便生成一個重載函數(shù),該重載函數(shù)的函數(shù)體與函數(shù)模板的函數(shù)體相同。這個根據(jù)函數(shù)模板生成的重載函數(shù)稱為模板函數(shù)。,函數(shù)模板與模板函數(shù)的區(qū)別如下: (1)函數(shù)模板不是一個函數(shù),而是一組函數(shù)的模板,在定義中使用了參數(shù)類型。 (2)模板函數(shù)是一種實實在在的函數(shù)定義,它的函數(shù)體與某個函數(shù)模板的函數(shù)體相同。 編譯系統(tǒng)遇到模板函數(shù)調用時,將生成可執(zhí)行代碼。 函數(shù)模板是定義重載函數(shù)的一種工具。一個函數(shù)模板只為一種原型函數(shù)生成一個模板函數(shù),不同原型的模板函數(shù)是重載的。這樣就使得一個函數(shù)只需編碼一次就能用于某個范圍的不同類型的對象上。 因此
17、,可以說函數(shù)模板是提供一組重載函數(shù)的樣板。,5.3 類模板和模板類,使用類模板(也稱為類屬類或類生成類)機制,用戶可以為類定義一種模式,使得類中的某些數(shù)據(jù)成員、某些成員函數(shù)的參數(shù)和某些成員函數(shù)的返回值,可以是任意類型的。 類模板不再代表一個具體的、實際的類,而是代表一類類。,1. 類模板的定義,定義類模板,包含兩方面內(nèi)容: 定義類; 在類定義體外定義成員函數(shù)。 1) 定義類的一般形式: template /模板聲明 class Name /類的定義 ;,例1:向量類模板定義。,template class Vector T *data; int size; public: Vector(int
18、 i) data=new Ti; Vector() delete data; T ,例2:一個單鏈表類模板的定義。,template class List/定義通用單鏈表類模板List,有一個模板參數(shù)T public: List(); /聲明構造函數(shù) void Add(T ,2) 在類定義體外定義成員函數(shù),如果在類定義體外定義成員函數(shù)時,如果該成員函數(shù)中有模板參數(shù),則需先進行模板聲明,而且用類模板名,而不是用類名來限定函數(shù)名,即在函數(shù)名前的類名后綴上“”。其一般形式為: template 函數(shù)返回值類型 類名:成員函數(shù)名(形參表) /函數(shù)體 ,例:類模板List中成員函數(shù)Add()和Remov
19、e()在類體外定義。,template void List:Add(T / 將新結點的地址賦給頭指針 template void List:Remove(T,例:,List intList; 表示將類模板List的類型參數(shù)T全部替換成int 型,從而創(chuàng)建一個具體的整型鏈表類,并生成該具體類的一個對象intList。 List charList; 表示將類模板List的類型參數(shù)T全部替換成char 型,從而創(chuàng)建一個具體的字符鏈表類,并生成該具體類的一個對象charList。,比較:類模板與模板類的區(qū)別。,類模板是模板的定義,不是一個實實在在的類,定義中用到通用類型參數(shù)。 模板類是實實在在的類定義
20、,是類模板的實例化。類定義中參數(shù)被實際類型所代替。 例: 見例exec11.5。,3. 類模板的派生,既可以從類模板派生出類模板,也可以派生出普通類(非模板類)。主要有以下幾種形式: 從類模板派生出類模板; 從類模板派生出普通類; 從普通類派生出類模板。,1) 從類模板派生出類模板,從類模板派生出新的類模板的格式如下所示: template class Base ; template class Derived: public Base ; 與定義一般派生類的格式類似,只是在指出它的父類時要加上模板參數(shù)。如,Base 。,例:見例exec11.6。,2) 從類模板派生出普通類,從類模板派生出一
21、個普通類的格式如下所示: template class Base ; class Derived: public Base ; 首先,作為新派生出來的普通類的父類,必須是類模板實例化后生成的模板類。例如上面的Base; 其次,在派生類定義之前不需要模板聲明語句template 。,例:見例exec11.7。,3) 從普通類派生出類模板,在聲明一個類模板時,可以盡可能將類模板中與虛擬類型參數(shù)無關的成員剝離出來,構成一個普通類,作為類模板的基類。因此,從普通類派生出類模板的情況也是十分常見的。 例: class Base ; template class Derived:public Base T
22、 data; ,模板的派生甚至可以繼承一個未知的基類,也就是說,繼承哪個基類由模板參數(shù)決定。 例: 見例exec11.8。,template class Derived:public T public: Derived():T() cout x; Derived y; Derived z; return 0; ,小 結,模板的概念: 是實現(xiàn)代碼重用機制的一種工具,它可以實現(xiàn)類型參數(shù)化,即把類型定義為參數(shù),從而實現(xiàn)代碼的可重用性。 模板的分類:函數(shù)模板和類模板 函數(shù)模板和模板函數(shù) 函數(shù)模板的定義和使用方法; 函數(shù)模板與模板函數(shù)的區(qū)別。 類模板和模板類 類模板的定義和使用方法; 類模板與模板類的區(qū)別; 類模板的派生(3種形式)。,思考題:,1已知 void Sort(int a,int size); void Sort(double a,int size); 是一個函數(shù)模板的兩個實例,其功能是將數(shù)組a中的前size個元素按從小到大順序排列。試設計這個函數(shù)模板。,#include using namespace std; template T Sum(T *ar
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 上海售電合同范本
- 兄弟爭房子合同范本
- 農(nóng)村魚塘承包合同范本
- 合作協(xié)議合同范本4人
- 買賣見證合同范本
- 冶煉設備租賃合同范本
- 代理英國租房合同范本
- 出租車成本監(jiān)審合同范本
- 醫(yī)療設備轉租合同范本
- 含租房屋銷售合同范例
- 2025年湖南環(huán)境生物職業(yè)技術學院單招職業(yè)技能測試題庫一套
- 2025年黑龍江農(nóng)業(yè)經(jīng)濟職業(yè)學院單招職業(yè)傾向性測試題庫參考答案
- 2025年廣東省深圳法院招聘書記員招聘144人歷年高頻重點模擬試卷提升(共500題附帶答案詳解)
- 變電站電網(wǎng)側儲能項目可行性研究報告
- 新版統(tǒng)編版一年級道德與法治下冊全冊教案(完整版)教學設計含教學反思
- 4.2 同學相伴 第二課時 課件 2024-2025學年三年級下冊道德與法治 統(tǒng)編版
- 2025年春季學期學校德育工作計劃安排表(完整版)
- 2025年全球及中國調頻儲能行業(yè)頭部企業(yè)市場占有率及排名調研報告
- 2024年江西青年職業(yè)學院高職單招職業(yè)適應性測試歷年參考題庫含答案解析
- 2025年度會計人員繼續(xù)教育會計法律法規(guī)答題活動測試100題答案
- 消防維保年度工作計劃
評論
0/150
提交評論