![面向?qū)ο蟪绦蛟O(shè)計語言C++第07章-虛函數(shù)和多態(tài)性市公開課一等獎省賽課獲獎_第1頁](http://file4.renrendoc.com/view3/M02/38/16/wKhkFmY3hAuAJPAaAAFWg5pZRHE022.jpg)
![面向?qū)ο蟪绦蛟O(shè)計語言C++第07章-虛函數(shù)和多態(tài)性市公開課一等獎省賽課獲獎_第2頁](http://file4.renrendoc.com/view3/M02/38/16/wKhkFmY3hAuAJPAaAAFWg5pZRHE0222.jpg)
![面向?qū)ο蟪绦蛟O(shè)計語言C++第07章-虛函數(shù)和多態(tài)性市公開課一等獎省賽課獲獎_第3頁](http://file4.renrendoc.com/view3/M02/38/16/wKhkFmY3hAuAJPAaAAFWg5pZRHE0223.jpg)
![面向?qū)ο蟪绦蛟O(shè)計語言C++第07章-虛函數(shù)和多態(tài)性市公開課一等獎省賽課獲獎_第4頁](http://file4.renrendoc.com/view3/M02/38/16/wKhkFmY3hAuAJPAaAAFWg5pZRHE0224.jpg)
![面向?qū)ο蟪绦蛟O(shè)計語言C++第07章-虛函數(shù)和多態(tài)性市公開課一等獎省賽課獲獎_第5頁](http://file4.renrendoc.com/view3/M02/38/16/wKhkFmY3hAuAJPAaAAFWg5pZRHE0225.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
面向?qū)ο蟪绦蛟O(shè)計語言C++電子科技大學(xué)計算機學(xué)院1第1頁第七章虛函數(shù)和多態(tài)性C++使用多態(tài)性實現(xiàn)同一個消息,不一樣接收者采取不一樣響應(yīng)方式這種現(xiàn)象。多態(tài)性是一個事務(wù)有各種形態(tài)。在面向?qū)ο笳Z言中,普通這么描述多態(tài):向不一樣對象發(fā)送同一個消息,不一樣對象在接收時會產(chǎn)生不一樣行為。也就是說,每個對象能夠用自己方式去響應(yīng)共同消息。2第2頁第七章虛函數(shù)和多態(tài)性C++語言多態(tài)性有兩種類型:
靜態(tài)多態(tài)性和動態(tài)多態(tài)性。函數(shù)重載和運算符重載都是靜態(tài)多態(tài)性。在程序編譯時系統(tǒng)就能夠決定調(diào)用哪個函數(shù),所以靜態(tài)多態(tài)性又稱為編譯時多態(tài)性。動態(tài)多態(tài)性時程序運行過程中才動態(tài)確實定操作所針正確對象。它又稱為運行時多態(tài)性。動態(tài)多態(tài)性是經(jīng)過虛函數(shù)實現(xiàn)。3第3頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.1靜態(tài)多態(tài)性對于普通組員函數(shù)重載,可表示為下面方式:(1)在同一個類中重載;(2)在不一樣類中重載;(3)基類組員函數(shù)在派生類中重載;所以,重載函數(shù)訪問是在編譯時區(qū)分,這種程序運行之前就能夠在多個函數(shù)中確定當(dāng)前訪問函數(shù)方法稱為靜態(tài)多態(tài)性。4第4頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.1靜態(tài)多態(tài)性有以下三種區(qū)分方法:據(jù)參數(shù)特征加以區(qū)分,比如:Show(int,
char)與
Show(char*,
float)使用”::”加以區(qū)分,比如:Circle::Show有別于
Point::Show依據(jù)類對象加以區(qū)分ACircle.Show()調(diào)用
Circle::Show()5第5頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.1靜態(tài)多態(tài)性子類能夠重載父類組員:classA{public: voidfun()
{cout<<"InA"<<endl;}};classB
:
publicA{public: voidfun()
{cout<<"InB"<<endl;}};6第6頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.1靜態(tài)多態(tài)性
CCobj; Cobj.fun();
//調(diào)用C::fun() Cobj.B::fun();//調(diào)用B::fun() Cobj.A::fun();//調(diào)用A::fun() A&Aref=Cobj; Aref.fun();
//調(diào)用A::fun(),編譯器經(jīng)過類型確定調(diào)用哪個版本
B&Bref=Cobj; Bref.fun();
//調(diào)用B::fun() Bref.A::fun();//調(diào)用A::fun() A*Apointer=&Cobj; Apointer->fun();//調(diào)用A::fun()7第7頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.2基類和派生類指針與對象關(guān)系(1)能夠用指向基類指針指向其公有派生類對象基類指針訪問是派生對象擁有基類部分,派生類本身部分不能被基類指針訪問。指向派生類指針指向基類對象是不正確
(2)希望用基類指針訪問其公有派生類特定組員,必須將基類指針用顯示類型轉(zhuǎn)換為派生類指針。8第8頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性1.虛函數(shù)概念
一個指向基類指針可用來指向從基類公有派生任何對象。是
C++實現(xiàn)運行時多態(tài)性關(guān)鍵路徑。假如有多個或者多層派生類,經(jīng)過一個基類指針能夠訪問全部派生類對象組員函數(shù),這么就能夠?qū)崿F(xiàn)一個接口,多個實現(xiàn)訪問了。9第9頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性classBase{public: Base(inta){x=a;}
voidwho()
{cout<<"base"<<x<<"\n";}protected: intx;};10classFirst_d:publicBase{public:First_d(inta):Base(a){}voidwho()
{cout<<"Firstderivation"<<x<<"\n";}};classSec_d:publicBase{public:Sec_d(inta):Base(a)
{}voidwho()
{cout<<"Secondderivation"<<x<<"\n";}};第10頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性
Base*p; Basebase_obj(1); First_dfirst_obj(2); Sec_dsecond_obj(3);
p=&base_obj; p->who(); p=&first_obj; p->who();
p=&sec_obj; p->who();輸出?11第11頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性程序輸出是:
base1base2base3調(diào)用都是父類函數(shù)版本12第12頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性經(jīng)過父類指針來看,該指針所指向是父類對象。13x&Base::who()&First_d::who()p對于p是不可見第13頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性假如伴隨p所指向?qū)ο蟛灰粯?,p->who()能調(diào)用不一樣類中who()版本,這么就能夠用一個界面訪問多個實現(xiàn)版本。實際上,這表示了一個動態(tài)性質(zhì),函數(shù)調(diào)用依賴于運行時p所指向?qū)ο蟆?/p>
虛函數(shù)提供就是這種解釋機制。虛函數(shù)是在基類中被冠以virtual組員函數(shù),它提供了一個接口界面。14第14頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性虛函數(shù)能夠在一個或多個派生類中被重新定義,但要求在派生類中重新定義時,虛函數(shù)函數(shù)原型(包含返回類型,函數(shù)名,參數(shù)個數(shù),參數(shù)類型次序)必須完全相同。重寫上例。15第15頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性classBase{public: Base(inta){x=a;}
virtual
voidwho()
{cout<<"base"<<x<<"\n";}protected: intx;};16classFirst_d:publicBase{public:First_d(inta):Base(a){}voidwho()
{cout<<"Firstderivation"<<x<<"\n";}};classSec_d:publicBase{public:Sec_d(inta):Base(a)
{}voidwho()
{cout<<"Secondderivation"<<x<<"\n";}};第16頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)2.運行時多態(tài)性與虛特征(1)運行時多態(tài)性在帶有虛函數(shù)類中,編譯器設(shè)置一個指針,稱為虛指針vpointer(縮寫為VPTR)。編譯器對每個包含虛函數(shù)類創(chuàng)建一個虛表(稱為VTABLE),存放類虛函數(shù)地址。VPTR指向這個對象VTABLE。經(jīng)過基類指針做虛函數(shù)調(diào)用時,編譯器取得這個VPTR,找到該類VTABLE,并在其中查找對應(yīng)虛函數(shù)地址,完成動態(tài)匹配。17第17頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)18第18頁單界面、多實現(xiàn)classfigure
{protected:floatx,y;
public:
voidset_dim(floati,floatj=0)
{x=i;
y=j;}
virtualvoidshow_area()
{cout<<“Noarea\n”;
}
};
第19頁classtriangle:
publicfigure
{public:
voidshow_area()
{cout<<x*0.5*y<<“\n”;}
};
第20頁
classsquare:
publicfigure{
public:
voidshow_area()
{cout<<x*y<<“\n”;
}
};
第21頁classcircle:
publicfigure
{
public:
voidshow_area()
{
cout<<3.14*x*x;
}
};
第22頁voidmain()
{
figure*p;trianglet;squares;circlec;
p=&t;
p->set_dim(10.0,
5.0);
p->show_area();p=&s;
p->set_dim(10.0,
5.0);
p->show_area();
p=&c;
p->set_dim(9.0);
p->show_area();
}
第23頁各個派生類共享基類函數(shù)set_dim(floati,floatj=0);而對于計算面積,各個實際圖形有不一樣算法square、triangle和circle含有相同界面show_area()但它們對應(yīng)不一樣實現(xiàn)方法所以,函數(shù)show_area()定義為虛函數(shù)。第24頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)
一個組員函數(shù)什么時候需要申明為虛函數(shù)呢?首先考慮組員函數(shù)所在類是否會做為基類。然后看組員函數(shù)在類繼承后有沒有功效被修改?假如希望修改其功效,普通將它申明為虛函數(shù)。還應(yīng)該考慮對組員函數(shù)調(diào)用是經(jīng)過對象名還是基類指針或引用去訪問。假如經(jīng)過基類指針或引用去訪問,則申明為虛函數(shù)。25第25頁第26頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)(2)虛特征用虛函數(shù)實現(xiàn)運行時多態(tài)性關(guān)鍵之處是,必須用指向基類指針(或者引用)訪問虛函數(shù)。盡管能夠像調(diào)用其它組員函數(shù)那樣顯式地用對象名來調(diào)用一個虛函數(shù),但只有在一個指向基類指針(或者引用)訪問虛函數(shù)時,運行時多態(tài)性才能實現(xiàn)。這時,稱為函數(shù)含有虛特征。27第27頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)基類函數(shù)含有虛特征條件是:在基類中,將該函數(shù)說明為虛(virtual)函數(shù)。這么能夠在派生類中重新定義此函數(shù),為它賦予新功效,并能夠方便調(diào)用。在類外定義虛函數(shù)時,無須再加virtual關(guān)鍵字。定義基類公有派生類;在基類公有派生類中原型一致地重載該虛函數(shù);定義指向基類指針變量,它指向基類公有派生類對象(或定義基類引用,它引用基類公有派生類對象)。28第28頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)重載一個虛函數(shù)時,要求函數(shù)名、返回類型、參量個數(shù)、參數(shù)類型和次序是完全相同。假如不一樣,會產(chǎn)生什么情況呢?(1)僅僅返回類型不一樣,其余相同。C++認為這是錯誤,因為僅僅返回類型不一樣函數(shù)本質(zhì)上是含糊。(2)函數(shù)原型不一樣,僅函數(shù)名相同,C++認為這是普通函數(shù)重載,此時虛特征丟失。(例7-5)29第29頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)定義虛函數(shù)時需要注意:(1)虛函數(shù)必須是類組員函數(shù)。不能將虛函數(shù)說明為全局(非組員)函數(shù),也不能說明為靜態(tài)組員函數(shù)。不能將友元說明為虛函數(shù),但虛函數(shù)能夠是另一個類友元。(2)析構(gòu)函數(shù)能夠是虛函數(shù),但結(jié)構(gòu)函數(shù)不能為虛函數(shù)。(3)一旦一個函數(shù)被說明為虛函數(shù),不論經(jīng)歷了多少派生類層,都將保持其虛特征。30第30頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)3.虛析構(gòu)函數(shù)請看這個例子:classbase{public: base(){cout<<"base()"<<endl;} ~base(){cout<<"~base()"<<endl;}};classderived:publicbase{public: derived(){cout<<"derived()"<<endl;} ~derived(){cout<<"~derived()"<<endl;}};31intmain(){
base*pb=newderived;
deletepb;
return0;}第31頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)請問程序輸出是什么?32程序輸出以下:base()derived();~base();結(jié)構(gòu)函數(shù)base()和derived()都被調(diào)用了,不過析構(gòu)函數(shù)只有~base()調(diào)用了。第32頁第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)原因很簡單:基類指針只調(diào)用基類組員函數(shù),不能夠調(diào)用派生類組員函數(shù),即使是析構(gòu)函數(shù)也是如此。假如希望能夠執(zhí)行派生類析構(gòu)函數(shù),則需要將基類析構(gòu)函數(shù)申明為虛析構(gòu)函數(shù):virtual~base()
{cout<<"~base()"<<endl;}當(dāng)基類析構(gòu)函數(shù)申明為虛函數(shù)時,不論指針指向是同一類族中哪一個對象,當(dāng)對象撤消時,系統(tǒng)會采取動態(tài)關(guān)聯(lián),調(diào)用對應(yīng)析構(gòu)函數(shù),對該對象進行清理工作。33第33頁
假如希望經(jīng)過基類指針或者引用訪問派生類組員函數(shù),但基類功效比較抽象或者不能確定功效,能夠?qū)⒒惗x為抽象類,即只定義函數(shù)名字,沒有函數(shù)體,詳細功效由派生類添加第34頁第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類基類往往表示一些抽象概念。比如,shape是一個基類,它表示含有形狀東西,從shape能夠派生出封閉圖形和非封閉圖形兩個派生類。封閉圖形又能夠派生出橢圓形、多邊形,……這個類等級基類shape表達了一個抽象概念在shape中定義一個求面積函數(shù)顯然是無意義但能夠?qū)⑵湔f明為虛函數(shù),提供各派生類一個公共界面,并由各派生類提供求面積函數(shù)各自版本35第35頁第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類基類有些虛函數(shù)沒有定義是很正常,不過要求派生類必須重定義這些虛函數(shù),以使派生類有意義。為此,C++引入了純虛函數(shù)概念。純虛函數(shù)是一個在基類中說明虛函數(shù),它在該基類中沒有定義,要求任何派生類都必須定義自己版本。為說明一純虛函數(shù),使用以下普通形式:virtualtypefunc_name(參數(shù)表)=0;36第36頁第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類將一虛函數(shù)說明成純虛函數(shù),就要求任何派生類都應(yīng)該定義自己實現(xiàn)。在結(jié)構(gòu)函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)時,采取靜態(tài)聯(lián)編,所以,在結(jié)構(gòu)函數(shù)和析構(gòu)函數(shù)中不能夠調(diào)用純虛函數(shù)。但其它組員函數(shù)能夠調(diào)用純虛函數(shù)。假如一個類最少有一個純虛函數(shù),那么就稱該類為抽象類。抽象類機制支持普通概念表示。抽象類只能用作其它類基類,抽象類不能建立對象。抽象類不能用作參數(shù)類型、函數(shù)返回類型或顯式轉(zhuǎn)換類型。但能夠申明抽象類指針和引用。37第37頁第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類純虛函數(shù)和抽象類例子:classshape{public:
virtualvoidrotate(int)=0; virtualvoiddraw()=0;};…38第38頁
用面向?qū)ο蠓椒▽崿F(xiàn)一個異質(zhì)鏈表。異質(zhì)是指鏈表中各表項內(nèi)容類型不要求相同第39頁(1)以大學(xué)環(huán)境為例,這里包含學(xué)生、職員和教師。希望對這些人信息進行管理(全部人員信息統(tǒng)計在一個鏈表中)。第40頁學(xué)生:姓名、年紀、身份證號碼、平均成績。職員:姓名、年紀、身份證號碼、小時工資。教師:姓名、年紀、身份證號碼、年工資。第41頁要求能實現(xiàn)三個操作:①插入。向異質(zhì)鏈表中增加一個學(xué)生、職員或教師信息。②刪除。從鏈表中刪除一個學(xué)生、職員和教師信息。③打印。顯示鏈表中全部信息。第42頁(2)對于一些既是學(xué)生又是教師雙重身份人,應(yīng)能單獨統(tǒng)計之。(3
溫馨提示
- 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)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二手房買賣合同示范文本
- 二手商品交易合同模板大全
- 云計算中心建設(shè)與運營合同(計算機行業(yè))
- 中外員工培訓(xùn)合同模板大全
- 上海市新建住宅銷售合同范本
- 交通監(jiān)控設(shè)備采購與供應(yīng)合同格式
- 個人與受贈方定向捐贈合同全文
- 個人借款合同樣本一
- 臨時工勞動合同書專業(yè)版
- 二手房交易無產(chǎn)權(quán)合同范本
- 中層領(lǐng)導(dǎo)的高績效管理
- 小小銀行家-兒童銀行知識、理財知識培訓(xùn)
- 物業(yè)公司縮減人員方案范本
- 機械基礎(chǔ)知識競賽題庫附答案(100題)
- 2022年上學(xué)期八年級期末考試數(shù)學(xué)試卷
- 閱讀理解特訓(xùn)卷-英語四年級上冊譯林版三起含答案
- 國庫集中支付培訓(xùn)班資料-國庫集中支付制度及業(yè)務(wù)操作教學(xué)課件
- 屋面及防水工程施工(第二版)PPT完整全套教學(xué)課件
- 2023年上海青浦區(qū)區(qū)管企業(yè)統(tǒng)一招考聘用筆試題庫含答案解析
- 2023年高一物理期末考試卷(人教版)
- 2023版押品考試題庫必考點含答案
評論
0/150
提交評論