面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言C++第07章-虛函數(shù)和多態(tài)性市公開(kāi)課一等獎(jiǎng)省賽課獲獎(jiǎng)_第1頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言C++第07章-虛函數(shù)和多態(tài)性市公開(kāi)課一等獎(jiǎng)省賽課獲獎(jiǎng)_第2頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言C++第07章-虛函數(shù)和多態(tài)性市公開(kāi)課一等獎(jiǎng)省賽課獲獎(jiǎng)_第3頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言C++第07章-虛函數(shù)和多態(tài)性市公開(kāi)課一等獎(jiǎng)省賽課獲獎(jiǎng)_第4頁(yè)
面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言C++第07章-虛函數(shù)和多態(tài)性市公開(kāi)課一等獎(jiǎng)省賽課獲獎(jiǎng)_第5頁(yè)
已閱讀5頁(yè),還剩45頁(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)介

面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言C++電子科技大學(xué)計(jì)算機(jī)學(xué)院1第1頁(yè)第七章虛函數(shù)和多態(tài)性C++使用多態(tài)性實(shí)現(xiàn)同一個(gè)消息,不一樣接收者采取不一樣響應(yīng)方式這種現(xiàn)象。多態(tài)性是一個(gè)事務(wù)有各種形態(tài)。在面向?qū)ο笳Z(yǔ)言中,普通這么描述多態(tài):向不一樣對(duì)象發(fā)送同一個(gè)消息,不一樣對(duì)象在接收時(shí)會(huì)產(chǎn)生不一樣行為。也就是說(shuō),每個(gè)對(duì)象能夠用自己方式去響應(yīng)共同消息。2第2頁(yè)第七章虛函數(shù)和多態(tài)性C++語(yǔ)言多態(tài)性有兩種類型:

靜態(tài)多態(tài)性和動(dòng)態(tài)多態(tài)性。函數(shù)重載和運(yùn)算符重載都是靜態(tài)多態(tài)性。在程序編譯時(shí)系統(tǒng)就能夠決定調(diào)用哪個(gè)函數(shù),所以靜態(tài)多態(tài)性又稱為編譯時(shí)多態(tài)性。動(dòng)態(tài)多態(tài)性時(shí)程序運(yùn)行過(guò)程中才動(dòng)態(tài)確實(shí)定操作所針正確對(duì)象。它又稱為運(yùn)行時(shí)多態(tài)性。動(dòng)態(tài)多態(tài)性是經(jīng)過(guò)虛函數(shù)實(shí)現(xiàn)。3第3頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.1靜態(tài)多態(tài)性對(duì)于普通組員函數(shù)重載,可表示為下面方式:(1)在同一個(gè)類中重載;(2)在不一樣類中重載;(3)基類組員函數(shù)在派生類中重載;所以,重載函數(shù)訪問(wèn)是在編譯時(shí)區(qū)分,這種程序運(yùn)行之前就能夠在多個(gè)函數(shù)中確定當(dāng)前訪問(wèn)函數(shù)方法稱為靜態(tài)多態(tài)性。4第4頁(yè)第七章虛函數(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ù)類對(duì)象加以區(qū)分ACircle.Show()調(diào)用

Circle::Show()5第5頁(yè)第七章虛函數(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頁(yè)第七章虛函數(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)過(guò)類型確定調(diào)用哪個(gè)版本

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頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.2基類和派生類指針與對(duì)象關(guān)系(1)能夠用指向基類指針指向其公有派生類對(duì)象基類指針訪問(wèn)是派生對(duì)象擁有基類部分,派生類本身部分不能被基類指針訪問(wèn)。指向派生類指針指向基類對(duì)象是不正確

(2)希望用基類指針訪問(wèn)其公有派生類特定組員,必須將基類指針用顯示類型轉(zhuǎn)換為派生類指針。8第8頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性1.虛函數(shù)概念

一個(gè)指向基類指針可用來(lái)指向從基類公有派生任何對(duì)象。是

C++實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性關(guān)鍵路徑。假如有多個(gè)或者多層派生類,經(jīng)過(guò)一個(gè)基類指針能夠訪問(wèn)全部派生類對(duì)象組員函數(shù),這么就能夠?qū)崿F(xiàn)一個(gè)接口,多個(gè)實(shí)現(xiàn)訪問(wèn)了。9第9頁(yè)第七章虛函數(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頁(yè)第七章虛函數(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頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性程序輸出是:

base1base2base3調(diào)用都是父類函數(shù)版本12第12頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性經(jīng)過(guò)父類指針來(lái)看,該指針?biāo)赶蚴歉割悓?duì)象。13x&Base::who()&First_d::who()p對(duì)于p是不可見(jiàn)第13頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性假如伴隨p所指向?qū)ο蟛灰粯?,p->who()能調(diào)用不一樣類中who()版本,這么就能夠用一個(gè)界面訪問(wèn)多個(gè)實(shí)現(xiàn)版本。實(shí)際上,這表示了一個(gè)動(dòng)態(tài)性質(zhì),函數(shù)調(diào)用依賴于運(yùn)行時(shí)p所指向?qū)ο蟆?/p>

虛函數(shù)提供就是這種解釋機(jī)制。虛函數(shù)是在基類中被冠以virtual組員函數(shù),它提供了一個(gè)接口界面。14第14頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)7.1.3虛函數(shù)與多態(tài)性虛函數(shù)能夠在一個(gè)或多個(gè)派生類中被重新定義,但要求在派生類中重新定義時(shí),虛函數(shù)函數(shù)原型(包含返回類型,函數(shù)名,參數(shù)個(gè)數(shù),參數(shù)類型次序)必須完全相同。重寫(xiě)上例。15第15頁(yè)第七章虛函數(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頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)2.運(yùn)行時(shí)多態(tài)性與虛特征(1)運(yùn)行時(shí)多態(tài)性在帶有虛函數(shù)類中,編譯器設(shè)置一個(gè)指針,稱為虛指針vpointer(縮寫(xiě)為VPTR)。編譯器對(duì)每個(gè)包含虛函數(shù)類創(chuàng)建一個(gè)虛表(稱為VTABLE),存放類虛函數(shù)地址。VPTR指向這個(gè)對(duì)象VTABLE。經(jīng)過(guò)基類指針做虛函數(shù)調(diào)用時(shí),編譯器取得這個(gè)VPTR,找到該類VTABLE,并在其中查找對(duì)應(yīng)虛函數(shù)地址,完成動(dòng)態(tài)匹配。17第17頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)18第18頁(yè)單界面、多實(shí)現(xiàn)classfigure

{protected:floatx,y;

public:

voidset_dim(floati,floatj=0)

{x=i;

y=j;}

virtualvoidshow_area()

{cout<<“Noarea\n”;

}

};

第19頁(yè)classtriangle:

publicfigure

{public:

voidshow_area()

{cout<<x*0.5*y<<“\n”;}

};

第20頁(yè)

classsquare:

publicfigure{

public:

voidshow_area()

{cout<<x*y<<“\n”;

}

};

第21頁(yè)classcircle:

publicfigure

{

public:

voidshow_area()

{

cout<<3.14*x*x;

}

};

第22頁(yè)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頁(yè)各個(gè)派生類共享基類函數(shù)set_dim(floati,floatj=0);而對(duì)于計(jì)算面積,各個(gè)實(shí)際圖形有不一樣算法square、triangle和circle含有相同界面show_area()但它們對(duì)應(yīng)不一樣實(shí)現(xiàn)方法所以,函數(shù)show_area()定義為虛函數(shù)。第24頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)

一個(gè)組員函數(shù)什么時(shí)候需要申明為虛函數(shù)呢?首先考慮組員函數(shù)所在類是否會(huì)做為基類。然后看組員函數(shù)在類繼承后有沒(méi)有功效被修改?假如希望修改其功效,普通將它申明為虛函數(shù)。還應(yīng)該考慮對(duì)組員函數(shù)調(diào)用是經(jīng)過(guò)對(duì)象名還是基類指針或引用去訪問(wèn)。假如經(jīng)過(guò)基類指針或引用去訪問(wèn),則申明為虛函數(shù)。25第25頁(yè)第26頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)(2)虛特征用虛函數(shù)實(shí)現(xiàn)運(yùn)行時(shí)多態(tài)性關(guān)鍵之處是,必須用指向基類指針(或者引用)訪問(wèn)虛函數(shù)。盡管能夠像調(diào)用其它組員函數(shù)那樣顯式地用對(duì)象名來(lái)調(diào)用一個(gè)虛函數(shù),但只有在一個(gè)指向基類指針(或者引用)訪問(wèn)虛函數(shù)時(shí),運(yùn)行時(shí)多態(tài)性才能實(shí)現(xiàn)。這時(shí),稱為函數(shù)含有虛特征。27第27頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)基類函數(shù)含有虛特征條件是:在基類中,將該函數(shù)說(shuō)明為虛(virtual)函數(shù)。這么能夠在派生類中重新定義此函數(shù),為它賦予新功效,并能夠方便調(diào)用。在類外定義虛函數(shù)時(shí),無(wú)須再加virtual關(guān)鍵字。定義基類公有派生類;在基類公有派生類中原型一致地重載該虛函數(shù);定義指向基類指針變量,它指向基類公有派生類對(duì)象(或定義基類引用,它引用基類公有派生類對(duì)象)。28第28頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)重載一個(gè)虛函數(shù)時(shí),要求函數(shù)名、返回類型、參量個(gè)數(shù)、參數(shù)類型和次序是完全相同。假如不一樣,會(huì)產(chǎn)生什么情況呢?(1)僅僅返回類型不一樣,其余相同。C++認(rèn)為這是錯(cuò)誤,因?yàn)閮H僅返回類型不一樣函數(shù)本質(zhì)上是含糊。(2)函數(shù)原型不一樣,僅函數(shù)名相同,C++認(rèn)為這是普通函數(shù)重載,此時(shí)虛特征丟失。(例7-5)29第29頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)定義虛函數(shù)時(shí)需要注意:(1)虛函數(shù)必須是類組員函數(shù)。不能將虛函數(shù)說(shuō)明為全局(非組員)函數(shù),也不能說(shuō)明為靜態(tài)組員函數(shù)。不能將友元說(shuō)明為虛函數(shù),但虛函數(shù)能夠是另一個(gè)類友元。(2)析構(gòu)函數(shù)能夠是虛函數(shù),但結(jié)構(gòu)函數(shù)不能為虛函數(shù)。(3)一旦一個(gè)函數(shù)被說(shuō)明為虛函數(shù),不論經(jīng)歷了多少派生類層,都將保持其虛特征。30第30頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)3.虛析構(gòu)函數(shù)請(qǐng)看這個(gè)例子: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頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)請(qǐng)問(wèn)程序輸出是什么?32程序輸出以下:base()derived();~base();結(jié)構(gòu)函數(shù)base()和derived()都被調(diào)用了,不過(guò)析構(gòu)函數(shù)只有~base()調(diào)用了。第32頁(yè)第七章虛函數(shù)和多態(tài)性7.1虛函數(shù)原因很簡(jiǎn)單:基類指針只調(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ù)時(shí),不論指針指向是同一類族中哪一個(gè)對(duì)象,當(dāng)對(duì)象撤消時(shí),系統(tǒng)會(huì)采取動(dòng)態(tài)關(guān)聯(lián),調(diào)用對(duì)應(yīng)析構(gòu)函數(shù),對(duì)該對(duì)象進(jìn)行清理工作。33第33頁(yè)

假如希望經(jīng)過(guò)基類指針或者引用訪問(wèn)派生類組員函數(shù),但基類功效比較抽象或者不能確定功效,能夠?qū)⒒惗x為抽象類,即只定義函數(shù)名字,沒(méi)有函數(shù)體,詳細(xì)功效由派生類添加第34頁(yè)第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類基類往往表示一些抽象概念。比如,shape是一個(gè)基類,它表示含有形狀東西,從shape能夠派生出封閉圖形和非封閉圖形兩個(gè)派生類。封閉圖形又能夠派生出橢圓形、多邊形,……這個(gè)類等級(jí)基類shape表達(dá)了一個(gè)抽象概念在shape中定義一個(gè)求面積函數(shù)顯然是無(wú)意義但能夠?qū)⑵湔f(shuō)明為虛函數(shù),提供各派生類一個(gè)公共界面,并由各派生類提供求面積函數(shù)各自版本35第35頁(yè)第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類基類有些虛函數(shù)沒(méi)有定義是很正常,不過(guò)要求派生類必須重定義這些虛函數(shù),以使派生類有意義。為此,C++引入了純虛函數(shù)概念。純虛函數(shù)是一個(gè)在基類中說(shuō)明虛函數(shù),它在該基類中沒(méi)有定義,要求任何派生類都必須定義自己版本。為說(shuō)明一純虛函數(shù),使用以下普通形式:virtualtypefunc_name(參數(shù)表)=0;36第36頁(yè)第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類將一虛函數(shù)說(shuō)明成純虛函數(shù),就要求任何派生類都應(yīng)該定義自己實(shí)現(xiàn)。在結(jié)構(gòu)函數(shù)和析構(gòu)函數(shù)中調(diào)用虛函數(shù)時(shí),采取靜態(tài)聯(lián)編,所以,在結(jié)構(gòu)函數(shù)和析構(gòu)函數(shù)中不能夠調(diào)用純虛函數(shù)。但其它組員函數(shù)能夠調(diào)用純虛函數(shù)。假如一個(gè)類最少有一個(gè)純虛函數(shù),那么就稱該類為抽象類。抽象類機(jī)制支持普通概念表示。抽象類只能用作其它類基類,抽象類不能建立對(duì)象。抽象類不能用作參數(shù)類型、函數(shù)返回類型或顯式轉(zhuǎn)換類型。但能夠申明抽象類指針和引用。37第37頁(yè)第七章虛函數(shù)和多態(tài)性7.2純虛函數(shù)和抽象類純虛函數(shù)和抽象類例子:classshape{public:

virtualvoidrotate(int)=0; virtualvoiddraw()=0;};…38第38頁(yè)

用面向?qū)ο蠓椒▽?shí)現(xiàn)一個(gè)異質(zhì)鏈表。異質(zhì)是指鏈表中各表項(xiàng)內(nèi)容類型不要求相同第39頁(yè)(1)以大學(xué)環(huán)境為例,這里包含學(xué)生、職員和教師。希望對(duì)這些人信息進(jìn)行管理(全部人員信息統(tǒng)計(jì)在一個(gè)鏈表中)。第40頁(yè)學(xué)生:姓名、年紀(jì)、身份證號(hào)碼、平均成績(jī)。職員:姓名、年紀(jì)、身份證號(hào)碼、小時(shí)工資。教師:姓名、年紀(jì)、身份證號(hào)碼、年工資。第41頁(yè)要求能實(shí)現(xiàn)三個(gè)操作:①插入。向異質(zhì)鏈表中增加一個(gè)學(xué)生、職員或教師信息。②刪除。從鏈表中刪除一個(gè)學(xué)生、職員和教師信息。③打印。顯示鏈表中全部信息。第42頁(yè)(2)對(duì)于一些既是學(xué)生又是教師雙重身份人,應(yīng)能單獨(dú)統(tǒng)計(jì)之。(3

溫馨提示

  • 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)論