版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、18:49:44,1,C++程序設(shè)計(jì)教程(第二版),第十四章 模板 Chapter 14 Template,清華大學(xué)出版社 錢 能,18:49:44,2,思考角度 C++程序是一些類型和函數(shù),編程就是設(shè)計(jì)類型和函數(shù),然后按C++的程序結(jié)構(gòu)來(lái)組織模板編程 世界上萬(wàn)事萬(wàn)物都具有相似性,許多類型和函數(shù)盡管處理的數(shù)據(jù)不同,但其行為也具有相似性,將相似的類型歸為類型族以及相似的函數(shù)歸為函數(shù)族的編程,就是模板編程編程方法的側(cè)
2、重點(diǎn) 面向?qū)ο缶幊探鉀Q類體系中的不同對(duì)象行為表現(xiàn) 模板編程解決獨(dú)立類之間的不同對(duì)象行為表現(xiàn) 多個(gè)獨(dú)立類可以是多個(gè)類繼承體系,因而,面向?qū)ο缶幊膛c模板編程是融合的.,18:49:44,3,第十四章內(nèi)容,函數(shù)模板(Function Template) 函數(shù)模板參數(shù)(Function Template Parameter) 類模板(Class Template) 實(shí)例化與定做(Instantiation & S
3、pecialization) 程序組織(Program Organization) 模板的多態(tài)(Template Polymorphism) 高級(jí)編程(Advanced Programming),18:49:44,4,1. 函數(shù)模板 ( Function Template ),理想的函數(shù)重載是針對(duì)不同的參數(shù)做不同的事.而形如:void swap(Type& a, Type& b){ Type t=a; a
4、=b; b=t;}的重載函數(shù)系所定義的行為序列卻相同.這種形式的重載意義不大.,18:49:44,5,,templatevoid swap(T& a, T& b){ T t=a; a=b; b=t;},定義函數(shù)模板來(lái)表示重載函數(shù)系:,模板形參,函數(shù)模板名,數(shù)據(jù)形參,函數(shù)模板定義體,18:49:44,6,templatevoid swap(T& a, T& b){ T t=a; a=b;
5、 b=t;}int fn(){ int ix=6, iy=7, ia=3, ib=5; swap(ix, iy); //產(chǎn)生函數(shù)定義體 swap(ia, ib); //不產(chǎn)生函數(shù)定義體 //...},函數(shù)模板用法:以函數(shù)模板名作調(diào)用的函數(shù)名,以數(shù)據(jù)實(shí)參作參數(shù)傳遞,,18:49:44,7,2. 函數(shù)模板參數(shù) ( Function Template Parameter ),數(shù)據(jù)參數(shù)是按值的性質(zhì)匹配的,所以相容類
6、型之間可以轉(zhuǎn)換類型參數(shù)是按名字匹配的,更為苛刻templatevoid swap(T& a, T& b){ T t=a; a=b; b=t;}int add(double a, double b){ return a+b;}int fn(){ int ia=3; double db=5.0; char s1[]="good", s2[]="better&q
7、uot;; int x = add(ia, db); // ok swap(ia, db); // error swap(s1, s2); // error},18:49:44,8,數(shù)據(jù)形參分:引用型參數(shù)(提倡用本項(xiàng))非引用型參數(shù)引用型參數(shù)分:引用型參數(shù)常量引用型參數(shù),18:49:44,9,常量引用型形參,其數(shù)據(jù)形參可以是臨時(shí)對(duì)象,所以,通過顯式轉(zhuǎn)換可以規(guī)定模板的產(chǎn)生形式.但是,不
8、能被隱式轉(zhuǎn)換的數(shù)據(jù)形參,其顯式模板類型指定失效:templateT const& max(T const& a, T const& b){ return a (ia, db); db = max(static_cast(ia), db); db = max(&ia, db); //error},18:49:44,10,引用型形參,其數(shù)據(jù)形參與數(shù)據(jù)實(shí)參捆綁,故數(shù)據(jù)實(shí)參應(yīng)為左值表達(dá)式:te
9、mplatevoid swap(T& a, T& b){ T t=a; a=b; b=t;}int main(){ int ia=3; const int cb=5; swap(ia, 7); // error:7不是左值 swap(ia, 7); // error:哪怕類型指定也不濟(jì) swap(cb, 7); // error:con
10、st int會(huì)引起操作錯(cuò)誤 swap(ia, 7); // error:同上},18:49:44,11,函數(shù)模板重載,參數(shù)有不同的形式(是否引用,是否常量,甚至是否特殊類型),不同形式的參數(shù),其行為不同,這是模板重載的前提.例如:字串比較很特殊,指針比較與對(duì)象比較亦不同,則:templateT const& max(T const& a, T const& b){ return a T* con
11、st& max(T* const& a, T* const& b){ return *a < *b ? b : a;}const char* const& max(const char* const& a, const char* const& b){ return strcmp(a,b) < 0 ? b : a;}int main(){ int ia=3
12、, ib=7; char *s1=”hello”, *s2=”hell”; cout<<*max(&ia, &ib)<<”\n”; // match the second template cout<<max(s1, s2)<<”\n”; // match the max function cout<<max(ia, ib)<&l
13、t;”\n”; // match the first template},18:49:44,12,3. 類模板 ( Class Template ),有些類,比如容器類,處理一種類型的對(duì)象與處理另一種類型的對(duì)象方法一樣,但是就因?yàn)樘幚淼膶?duì)象類型不同,而使該類必須重新定義.例如:CatList, DogList, RabbitList等,18:49:44,13,通過模板類定義,可以解決代碼冗繁問題:templatecl
14、ass Node{public: Node(const T& d):c(d),next(0),pref(0){} T c; Node *next, *pref;};,18:49:44,14,又例如下面的模板類定義,含有模板類的成員:templateclass List{ Node *first, *last;public: List(); void add(const T& c);
15、 void remove(const T& c); Node* find(const T& c)const; void print()const; ~List();};,18:49:44,15,與類定義相似,成員函數(shù)的定義一般放在類定義的外部,與類定義分開.以有利于程序的組織.放在模板類定義外部的成員函數(shù)的定義形式為:,templateList::List():first(0),last(0){}tem
16、platevoid List::add(const T& n){ Node* p = new Node(n); p->next = first; first = p; (last ? p->next->pref : last) = p;},List構(gòu)造函數(shù),18:49:44,16,類模板(class template):側(cè)重于模板的描述(聲明或定義),例如:Templateclass L
17、ist;//類模板聲明template //類模板定義class List{ Node *first, *last;public: List(); void add(const T& c); void remove(const T& c); Node* find(const T& c)const; void print()const; ~List();};,模
18、板類(template class):側(cè)重于模板的使用形式例如:List //T為類型形參List //Dog是類型實(shí)參形如List形式的類,不管T是形參還是實(shí)參,本書都稱之為為模板類,18:49:44,17,高級(jí)模板概念中,類模板聲明,如:Templateclass List等同于帶有形式類型參數(shù)的模板類,如:List并將其作為一種類型看待所以本質(zhì)上不區(qū)分類模板與模板類.,18:49:44,18,模板類的使
19、用將直接透入對(duì)象的構(gòu)造,因此,允許模板類帶有值參便理所當(dāng)然了.templateclass bitset;但是類型值參將導(dǎo)致不同的類模板描述,因而決定了不同的值參值,生成不同的模板類bitset a;bitset b;a = b; // error值參值應(yīng)為編譯能識(shí)別的常量,值參多為整型.,18:49:44,19,4. 實(shí)例化與定做 ( Instantiation & Specialization ),
20、實(shí)例化遵循一次定義原則第一次用特定的類型實(shí)參使用模板類時(shí),將引起類模板的實(shí)例化(產(chǎn)生類定義).List dList;//產(chǎn)生實(shí)例化List eList;//不再實(shí)例化第一次用特定的類型實(shí)參使用模板函數(shù)時(shí),將引起函數(shù)模板的實(shí)例化(產(chǎn)生函數(shù)定義).,18:49:44,20,實(shí)例化與實(shí)施的操作有關(guān),構(gòu)造對(duì)象所觸發(fā)的實(shí)例化,只實(shí)例化其構(gòu)造函數(shù),不實(shí)例化類模板的其他成員函數(shù).但可以通過顯式請(qǐng)求,強(qiáng)制整體實(shí)例化.,template Li
21、st;//實(shí)例化整個(gè)模板類List dList;//實(shí)例化構(gòu)造函數(shù)dList.add(3.6);//實(shí)例化add成員dList.add(5.8);//不再實(shí)例化,只是簡(jiǎn)單調(diào)用List iList;//不再實(shí)例化iList.add(5);//不再實(shí)例化,18:49:44,21,對(duì)于特定的類型實(shí)參,希望其行為不同于類模板所規(guī)定的操作,可以根據(jù)該實(shí)參來(lái)定做,定做的模板稱為模板鑄件(或稱特制模板),如:templateclass
22、 List{ Node *first, *last;public: List(); void add(const Cat& c); void remove(const Cat& c); Node* find(const Cat& c)const; void print()const; ~List();};,18:49:44,22,模板鑄件可為類,亦可為模板.若為模板,則其定做稱為局部
23、定做.,templateclass A{ ... };局部定做1templateclass A{ … }; //A為模板局部定做2templateclass A{ … }; //A為模板使用時(shí)要注意:A dCat; //按A匹配A dd;//按A匹配A cCat; //錯(cuò):A還是A?,18:49:44,23,5. 程序組織 ( Program Organization ),包含方式模板使用的方式,
24、不但創(chuàng)建了模板函數(shù)定義或模板類定義,還實(shí)施了函數(shù)調(diào)用,或者創(chuàng)建了對(duì)象,實(shí)施了對(duì)象操作.因此,除了需要函數(shù)模板聲明或類模板定義之外,還需要函數(shù)模板定義和類模板的實(shí)現(xiàn).也就是說,任何使用模板之前,編譯應(yīng)該能夠事先看到整個(gè)模板的說明.這就是包含方式的由來(lái).,18:49:44,24,模板使用//x.cpp#include”tlist.h”int main(){ List dList; dList.add(3.6); dLis
25、t.print(); List iList; iList.add(5); iList.add(8); iList.print();},模板說明// tlist.h#ifndef TLIST#define TLISTtemplatestruct Node{ ... };template //類模板定義class List{ ... };template //類模板成員函數(shù)實(shí)現(xiàn)List::List():f
26、irst(0),last(0){}templatevoid List::add(const T& n){ ... }// ...#endif // TLIST,18:49:44,25,分離方式通過關(guān)鍵字export來(lái)規(guī)定編譯和鏈接模板的方式,分離模板定義和模板實(shí)現(xiàn),讓使用模板者無(wú)須與模板實(shí)現(xiàn)見面.,18:49:44,26,模板實(shí)現(xiàn)// tlist.cpp#include”tlist.h”export te
27、mplateList::List():first(0),last(0){}export templatevoid List::add(const T& n){ ... }// ...,模板定義// tlist.h#ifndef TLIST#define TLISTtemplatestruct Node{ ... };export template //類模板定義class List{ ... };#end
28、if // TLIST,模板使用(與包含方式同)//x.cpp#include”tlist.h”int main(){ List dList; dList.add(3.6); dList.print(); List iList; iList.add(5); iList.add(8); iList.print();},18:49:44,27,6. 模板的多態(tài) ( Template Polymo
29、rphism ),不同類型的對(duì)象,作相同名字的操作,卻表現(xiàn)為不同的行為,便是多態(tài)虛函數(shù)所表現(xiàn)的多態(tài)是基于類繼承體系的,而模板的多態(tài)卻適合于任何孤立的類.由對(duì)象捆綁同名操作,以求識(shí)別不同的行為,得等到運(yùn)行過程中獲得傳遞的對(duì)象之后——?jiǎng)佣鄳B(tài).由實(shí)例化模板類,進(jìn)而創(chuàng)建對(duì)象,來(lái)規(guī)定對(duì)象的操作,便可以在對(duì)象創(chuàng)建中,確定對(duì)象未來(lái)將要進(jìn)行捆綁的同名操作的行為——靜多態(tài).,18:49:44,28,靜多態(tài)class Dog{…};class C
30、at{…};templateclass List{…};templatevoid fn(list& a){ a.print(); //其行為取決于a的類型 }int main(){ List dlist; dlist.add(…); List clist; clist.add(…); fn(dlist);//定義void fn(list) fn(clist);//定義fn的重載函數(shù)},
31、18:49:44,29,7. 高級(jí)編程 ( Advanced Programming ),靜多態(tài)——無(wú)須動(dòng)態(tài)聯(lián)編,而同樣可以實(shí)現(xiàn)多態(tài)// application1.cpp#include”interfacetv.h”Templatevoid operating(TV& tv){ tv.adjustVolume(); tv.switchChannel();},// interfacetv.h#ifndef H
32、EADER_INTERFACETV#define HEADER_INTERFACETVtemplateclass InterfaceTV{ TV tv;public: void adjustVolume(){ tv.adjustVolume(); } void switchChannel(){ tv.switchChannel(); }};#endif // HEADER_INTE
33、RFACETV,18:49:44,30,抽象編程代碼// application2.cpp#include”interfacetv.h”#include”sony.h”#include”natinal.h”void f(){ InterfaceTV ts; ts.operating(); InterfaceTV tn; tn.operating();},sony類定義與實(shí)現(xiàn)代碼// sony.h// so
34、ny.cppNational類定義與實(shí)現(xiàn)代碼// national.h// national.cpp,18:49:44,31,泛型編程,模板編程是歸納類族和函數(shù)族的編碼工作.泛型編程是解決具體問題的編程,包括應(yīng)用編程.與面向?qū)ο缶幊滔嗪魬?yīng),是一種利用靜多態(tài)技術(shù)來(lái)展示對(duì)象行為的編程方法.由于實(shí)際情況中,充斥著類的繼承體系與別的類繼承體系甚至孤立類的交互作用,所以,問題解決方案中往往面向?qū)ο缶幊膛c泛型編程兩種方法并用.動(dòng)多態(tài)與靜多
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- c++程序設(shè)計(jì)教程
- c++程序設(shè)計(jì)教程修訂版
- c++程序設(shè)計(jì)教程_1-
- c++程序設(shè)計(jì)教程2-
- c語(yǔ)言程序設(shè)計(jì)學(xué)習(xí)指導(dǎo)第二版 答案
- c++程序設(shè)計(jì)教程與實(shí)驗(yàn)指導(dǎo)
- c語(yǔ)言程序設(shè)計(jì)第二版習(xí)題參考題答案
- c++程序設(shè)計(jì)
- c++程序設(shè)計(jì)
- 譚浩強(qiáng)c++程序設(shè)計(jì)(ppt版)
- java程序設(shè)計(jì)(第二版)課后習(xí)題答案
- 《程序設(shè)計(jì)基礎(chǔ)(c++)》實(shí)驗(yàn)教程及完整答案
- 《程序設(shè)計(jì)基礎(chǔ)c++》
- [工學(xué)]c++程序設(shè)計(jì)
- 《c++語(yǔ)言程序設(shè)計(jì)》課程輔導(dǎo)二
- c++程序語(yǔ)言教程 第二章
- c c++程序設(shè)計(jì)課后答案
- c++程序設(shè)計(jì)復(fù)習(xí)筆記
- c++課程設(shè)計(jì)--c++程序設(shè)計(jì)語(yǔ)言
- c++課程設(shè)計(jì)-- c++面向?qū)ο蟪绦蛟O(shè)計(jì)
評(píng)論
0/150
提交評(píng)論