版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
C++程序設(shè)計(jì)教程(第二版)第十二章
多態(tài)Chapter12
Polymorphism
清華大學(xué)出版社
錢能4/18/20231第十章內(nèi)容繼承召喚多態(tài)(InheritanceSummonupPolymorphism)
抽象編程的困惑(AbstractProgrammingPerplexing)
虛函數(shù)(VirtualFunction)
避免虛函數(shù)誤用(AvoidingMisusingVirtualFunction)
精簡共性的類(SimplifyClasswithGenerality)
多態(tài)編程(PolymorphicProgramming)
類型轉(zhuǎn)換(TypeConversions
)4/18/202321.繼承召喚多態(tài)(InheritanceSummonupPolymorphism)
祖孫互易的說明:晚輩是前輩的后繼,晚輩是前輩的一種.反之不確,前輩不是晚輩,也不是晚輩的一種.這一概念也影響到類的繼承操作,甚至其指針操作:Student是GraduateStudent的祖先.則:Students,*pS;GraduateStudent
gs,*pGS;s=gs;//okgs=s;//errorpS=static_cast<Student*>(&gs);//okpGS=static_cast<GraduateStudent*>(&s);//error4/18/20233同化效應(yīng)
classStudent{public://...voiddisplay(){cout<<“UnderGraduate\n”;}};classGraduateStudent:publicStudent{public://...voiddisplay(){cout<<“Graduate\n";}};Studentds;GraduateStudent
gs;ds.display();gs.display();對于右邊的類和對象操作,則有下列結(jié)果:UnderGraduateGraduate但是,若執(zhí)行s=gs;則執(zhí)行s.display()的結(jié)果為:UnderGraduate說明,gs雖然是研究生對象,但在賦值給大學(xué)生對象操作之后,被大學(xué)生同化了,喪失了研究生的本性.4/18/20234同化效應(yīng)蔓延到指針操作
Students,*ps;GraduateStudent
gs;ps=&s;ps->display();ps=static_cast<Student*>(&gs);ps->display();結(jié)果:UnderGraduateGraduate這意味著子類對象就是父類對象的性質(zhì)是一句空話.因?yàn)椴僮髌饋碓瓉硎菍⒆宇悓ο蟠直┑耐?,根本扼殺了子類對象的個(gè)性.于是,子類對象與父類對象共存的容器便失去了意義,因?yàn)槿萜髦袥]有子類對象,全部同化成一種父類對象了,世界失去了豐富多彩性!4/18/20235關(guān)鍵技術(shù)
voidfn(Student&x){//...}intmain(){Students;
GraduateStudent
gs;
fn(s);//顯示大學(xué)生信息
fn(gs);//顯示研究生信息}結(jié)果:UnderGraduateGraduate子類對象賦值給父類對象,使得子類對象不復(fù)存在,這沒有異議.Students=gs;否則,讓父類對象行使子類職能就太離譜了.當(dāng)子類對象的地址賦給父類對象指針(或引用)時(shí),應(yīng)讓子類對象維持其狀態(tài)的完整性,并且還要顯露其子類的特征.即多態(tài)性:4/18/202362.抽象編程的困惑(AbstractProgrammingPerplexing)類型域方案可以做到,即實(shí)現(xiàn)fn函數(shù)如下:void
fn(Student&x){
switch(x.type){
case
Student::STUDENT:
x.calcTuition();break;
case
Student::GRADUATESTUDENT:
GraduateStudent&rx=static_cast<GraduateStudent&>(x);
rx.calcTuition();break;}}但不敢恭維這種方法,因?yàn)樗鼘?dǎo)致類編程與應(yīng)用編程互相依賴,因而破壞了只關(guān)注局部細(xì)節(jié)的抽象編程.4/18/20237破壞抽象編程的后果是:可維護(hù)性,可擴(kuò)展性受到傷害.若增加一個(gè)博士類,則類代碼與應(yīng)用程序代碼都得改,而這本來不是應(yīng)用程序的份內(nèi)事.因而呼吁從語言內(nèi)部來支持這種多態(tài)性.4/18/202383.虛函數(shù)(VirtualFunction)
于是應(yīng)用程序便有多態(tài),而且fn函數(shù)實(shí)現(xiàn)非常簡捷:
void
fn(Student&x){
x.display()
}
intmain(){
Students;
GraduateStudent
gs;
fn(s);//顯示大學(xué)生信息
fn(gs);//顯示研究生信息
}
結(jié)果:
UnderGraduate
Graduate類中采用虛函數(shù):
classStudent{
public:
virtualvoiddisplay(){
cout<<“UnderGraduate\n”;
}
};
class
GraduateStudent
:publicStudent{
public:
virtualvoiddisplay(){
cout<<“Graduate\n”;
}
};
注:子類同名函數(shù)上的virtual可省4/18/20239多態(tài)性使得應(yīng)用程序使用類體系中的祖孫對象共存的復(fù)雜局面達(dá)到了一種編程自在境界.
程序員從使用孤立的類(抽象數(shù)據(jù)類型),到使用分層的類,并且讓各種對象“同場競技”,充分展現(xiàn)其個(gè)性.嘗到了對象化編程的真正樂趣.
C++類機(jī)制的虛函數(shù)就是沖著讓類編程實(shí)質(zhì)性地支持應(yīng)用編程中對家族化對象操作依賴的目的,從而面向?qū)ο髞矸治觥⒃O(shè)計(jì)和解決問題.4/18/2023104.避免誤用虛函數(shù)(AvoidingMisusingVirtualFunction)
classBase{public:
virtualvoid
fn(intx){
cout<<"Base\n";}};classSub:publicBase{public:
virtualvoid
fn(doublex){
cout<<"Sub\n";}};void
test(Base&b){b.fn(3.5);}intmain(){
test(Base());
test(Sub());}子類重載父類成員函數(shù)不能傳播“虛”性
右邊程序的運(yùn)行結(jié)果說明了這一點(diǎn):
BaseBase4/18/202311函數(shù)重載對于編譯識(shí)別來說,返回類型是不起作用的.voidfn(int);int
fn(int);對于fn(2);無法判斷應(yīng)該調(diào)用哪個(gè)函數(shù).而使調(diào)用遭遇編譯失?。畬τ谔摵瘮?shù)來說,聲明:virtualBase*fn();virtualSub*fn();應(yīng)看作不能分辨其多態(tài)調(diào)用的虛函數(shù),但卻引編譯認(rèn)為是同一個(gè)虛函數(shù)而獲得通過.這是語言技術(shù)上的一種處理,事實(shí)上,如果一個(gè)多態(tài)函數(shù)正在處理Sub類的對象,則它仍可以通過返回的Sub對象指針,繼續(xù)處理Sub對象,似乎更自然4/18/202312注意事項(xiàng):多態(tài)性是通過成員函數(shù)捆綁不同類型的對象來體現(xiàn)的,所以,虛函數(shù)一定是成員函數(shù),而且,靜態(tài)成員函數(shù)都不行,因?yàn)樗焕墝ο?,同樣,?gòu)造函數(shù)也不行,因?yàn)樗划a(chǎn)生對象,也不捆綁對象.可是,析構(gòu)函數(shù)卻可以是虛函數(shù),事實(shí)上,鼓勵(lì)類繼承體系中的每個(gè)類最好其析構(gòu)函數(shù)都是虛函數(shù).一旦設(shè)置了虛函數(shù),就與編譯器達(dá)成了滯后聯(lián)編的協(xié)議,函數(shù)必定分離于當(dāng)前運(yùn)行的模塊,因而就不可能是內(nèi)聯(lián)函數(shù)了.4/18/2023135.精簡共性的類(SimplifyClasswithGenerality)孤立的類之間有一些共性,希望減少一些冗余代碼.通常不能因此而構(gòu)成上下級(jí)關(guān)系的類層次,因?yàn)闀?huì)產(chǎn)生不良反應(yīng):基類如果擴(kuò)展功能,勢必連累子類.4/18/2023146.多態(tài)編程(PolymorphicProgramming)將共性的類通過繼承由共性構(gòu)成的基類來實(shí)現(xiàn)或許會(huì)比較明智.因?yàn)閮烧叩臄U(kuò)展彼此之間不會(huì)帶來干擾.而且還可任意派生子類類的繼承體系決定之后,其基類的多態(tài)成員函數(shù)也可確定.通??梢栽谧宇愔g進(jìn)行比較,同名不同功能的函數(shù)往往可以置成虛函數(shù).classAccount{protected://...public:virtualvoiddisplay()const;virtualvoidwithdrawal(doubleamount){}};4/18/202315多態(tài)編程中,會(huì)遇到各種子類混在一個(gè)集合中的情形,這正是多態(tài)大展身手的時(shí)候.針對左邊的類體系,有多態(tài)的應(yīng)用代碼:vector<shape*>a;//...for(inti=0;i<a.size();++i)
a[i]->area();classShape{public://...
virtualvoidarea(){}};class
Circle:publicShape{public:
voidarea(){…}//...};class
Triangle:publicShape{public:
voidarea(){…}//...};//...4/18/2023167.類型轉(zhuǎn)換(TypeConversions
)調(diào)用虛函數(shù)是一種多態(tài)的方法,它是將運(yùn)行中無法知道的對象交給系統(tǒng)去自動(dòng)辨認(rèn)類型從而作出準(zhǔn)確的操作使用動(dòng)態(tài)轉(zhuǎn)型策略:另一種實(shí)現(xiàn)是在運(yùn)行中,判斷對象的類型,從而可以準(zhǔn)確的捆綁調(diào)用確定的成員函數(shù),這是一種主動(dòng)辨認(rèn)對象類型的編程策略4/18/202317辨認(rèn)對象的類型,首先應(yīng)該知道其屬于哪個(gè)類系.然后確定要判斷的子類名稱.再行編碼.例如,針對每個(gè)對象進(jìn)行操作:Savings類對象,余額增加以1%計(jì)算的利息;Checking類對象,余額增加以0.05%計(jì)算的利息vector<Account*>a;//...Checking*pC;Savings*pS;for(inti=0;i<a.size();++i){
if(pC=dynamic_cast<Checking*>(a[i]))
pC->deposit(pC->getBalan()*0.05);
elseif(pS=dynamic_cast<Savings*>(&a[i]))
pS->deposit(pS->getBalan()*0.1);
a[i]->display();}動(dòng)態(tài)轉(zhuǎn)型4/18/202318動(dòng)態(tài)轉(zhuǎn)型只限于多態(tài)類,而靜態(tài)轉(zhuǎn)型適合更一般的類對象.例如,沒有多態(tài)性的學(xué)生與研究生之間的轉(zhuǎn)換:Student*ps=static_cast<Student*>(&gs);例如:無類型指針到某類型指針的轉(zhuǎn)換:
void
fn(void*dd){Student*pp=static_cast<Student*>(&dd);//...}靜態(tài)轉(zhuǎn)型4/18/202319許多標(biāo)準(zhǔn)類庫函數(shù)的聲明為了適應(yīng)大多數(shù)編程場合,做了完美的設(shè)計(jì).例如,max:constchar*max(constchar*s1,constchar*s2){
returnstrcmp(s1,s2)>0?s1:
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 供熱工程招投標(biāo)合同管理安全
- 融資合作法律文
- 鋼結(jié)構(gòu)廠房防腐施工合同
- 熱帶雨林排水溝施工合同范本
- 農(nóng)產(chǎn)品冷藏倉庫租賃合同
- 玩具制造電動(dòng)工具租賃合同
- 冰球俱樂部租賃合同范本
- 資產(chǎn)保護(hù)實(shí)施細(xì)則
- 智能交通網(wǎng)絡(luò)施工合同范本
- 遺傳病和人類健康講解
- 初中九年級(jí)化學(xué)課件復(fù)分解反應(yīng)的條件“百校聯(lián)賽”一等獎(jiǎng)
- 冷庫安全施工方案
- 《企劃案撰寫》課件
- 人是如何學(xué)習(xí)的II:學(xué)習(xí)者、境脈與文化
- 妊娠易栓癥查房課件
- 《數(shù)據(jù)結(jié)構(gòu)與算法》教案
- 工程地質(zhì)調(diào)查規(guī)范
- 凈水設(shè)備采購務(wù)投標(biāo)方案技術(shù)標(biāo)
- 第15課《誡子書》課件(共31張)語文七年級(jí)上冊
- 人教版六年級(jí)上冊數(shù)學(xué)期末看圖列式計(jì)算專題訓(xùn)練
- GB/T 43321-2023銅及銅合金釬焊推薦工藝規(guī)范
評論
0/150
提交評論