C程序設(shè)計(jì)《多態(tài)性與虛函數(shù)》.ppt_第1頁(yè)
C程序設(shè)計(jì)《多態(tài)性與虛函數(shù)》.ppt_第2頁(yè)
C程序設(shè)計(jì)《多態(tài)性與虛函數(shù)》.ppt_第3頁(yè)
C程序設(shè)計(jì)《多態(tài)性與虛函數(shù)》.ppt_第4頁(yè)
C程序設(shè)計(jì)《多態(tài)性與虛函數(shù)》.ppt_第5頁(yè)
已閱讀5頁(yè),還剩24頁(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)介

1、1,C+程序設(shè)計(jì),多態(tài)性與虛函數(shù),2,第5章 多態(tài)性與虛函數(shù),什么是多態(tài)性 向上類(lèi)型轉(zhuǎn)換 功能早綁定和晚綁定 實(shí)現(xiàn)功能晚綁定虛函數(shù) 純虛函數(shù)和抽象類(lèi) 學(xué)生信息管理系統(tǒng)中的多態(tài)性,本章學(xué)習(xí)要點(diǎn),3,第5章 多態(tài)性與虛函數(shù),多態(tài)性是指用一個(gè)名字定義不同的函數(shù),這些函數(shù)執(zhí)行不同但又類(lèi)似的操作,從而可以使用相同的調(diào)用方式來(lái)調(diào)用這些具有不同功能的同名函數(shù)。 實(shí)現(xiàn)“一個(gè)接口,多種方法”,4,5.1 什么是多態(tài)性,多態(tài)性可以分為4類(lèi): 參數(shù)多態(tài) 包含多態(tài) 重載多態(tài) 強(qiáng)制多態(tài)。,5,5.1 什么是多態(tài)性,參數(shù)多態(tài)如函數(shù)模板和類(lèi)模板。 由函數(shù)模板實(shí)例化的各個(gè)函數(shù)都具有相同的操作,而這些函數(shù)的參數(shù)類(lèi)型卻各不相同。

2、同樣地,由類(lèi)模板實(shí)例化的各個(gè)類(lèi)都具有相同的操作,而操作對(duì)象的類(lèi)型是各不相同的。,6,5.1 什么是多態(tài)性,包含多態(tài)是研究類(lèi)族中定義于不同類(lèi)中的同名成員函數(shù)的多態(tài)行為,主要是通過(guò)虛函數(shù)來(lái)實(shí)現(xiàn)的。,7,5.1 什么是多態(tài)性,重載多態(tài)如函數(shù)重載、運(yùn)算符重載等。前面我們學(xué)習(xí)過(guò)的普通函數(shù)及類(lèi)的成員函數(shù)的重載都屬于重載多態(tài)。,8,5.1 什么是多態(tài)性,強(qiáng)制多態(tài)是指將一個(gè)變?cè)念?lèi)型加以變化,以符合一個(gè)函數(shù)(或操作)的要求,例如加法運(yùn)算符在進(jìn)行浮點(diǎn)數(shù)與整型數(shù)相加時(shí),首先進(jìn)行類(lèi)型強(qiáng)制轉(zhuǎn)換,把整型數(shù)變?yōu)楦↑c(diǎn)數(shù)再相加的情況,就是強(qiáng)制多態(tài)的實(shí)例。,9,5.2 向上類(lèi)型轉(zhuǎn)換,向上類(lèi)型轉(zhuǎn)換是指把一個(gè)派生類(lèi)的對(duì)象作為基類(lèi)的

3、對(duì)象來(lái)使用。 向上轉(zhuǎn)型中有三點(diǎn)需要我們特別注意。 向上類(lèi)型轉(zhuǎn)換是安全的。 向上類(lèi)型轉(zhuǎn)換可以自動(dòng)完成。 向上類(lèi)型轉(zhuǎn)換的過(guò)程中會(huì)丟失子類(lèi)型信息。,10,5.2 向上類(lèi)型轉(zhuǎn)換,【例5-1】一個(gè)向上類(lèi)型轉(zhuǎn)換的例子。 #include using namespace std; class B0 /基類(lèi)B0聲明 public: void display()coutdisplay(); /通過(guò)“對(duì)象指針-成員名”的形式調(diào)用display()成員函數(shù) int main() B0 b0; /聲明B0類(lèi)對(duì)象 B1 b1; /聲明B1類(lèi)對(duì)象 D1 d1; /聲明D1類(lèi)對(duì)象 B0 *p; /聲明B0類(lèi)指針p p=,1

4、1,5.3 功能早綁定和晚綁定,功能早綁定(編譯時(shí)的多態(tài)性):綁定是在程序編譯階段完成。功能早綁定時(shí),系統(tǒng)用實(shí)參與形參進(jìn)行匹配,對(duì)于同名的重載函數(shù)便根據(jù)參數(shù)上的差異進(jìn)行區(qū)分,然后進(jìn)行綁定,從而實(shí)現(xiàn)了編譯時(shí)的多態(tài)性。 功能晚綁定(運(yùn)行時(shí)的多態(tài)性):綁定是在程序運(yùn)行階段完成的。即當(dāng)程序調(diào)用到某一函數(shù)名時(shí),才去尋找和連接其程序代碼,對(duì)面向?qū)ο蟪绦蛟O(shè)計(jì)而言,就是當(dāng)對(duì)象接收到某一消息時(shí),才去尋找和連接相應(yīng)的方法。,12,5.4 實(shí)現(xiàn)功能晚綁定虛函數(shù),成員函數(shù)的定義語(yǔ)法是: virtual 函數(shù)類(lèi)型 函數(shù)名(形參表) 函數(shù)體 ,13,5.2 向上類(lèi)型轉(zhuǎn)換,【例5-3】 有一個(gè)交通工具類(lèi)vehicle,將它

5、作為基類(lèi)派生出汽車(chē)類(lèi)motor_ vehicle ,再將汽車(chē)類(lèi)motor_ vehicle 作為基類(lèi)派生出小汽車(chē)類(lèi)car和卡車(chē)類(lèi)truck,聲明這些類(lèi)并定義一個(gè)虛函數(shù)用來(lái)顯示各類(lèi)信息。程序如下: #include using namespace std; class vehicle/基類(lèi)vehicle聲明 public: virtual void message() /虛成員函數(shù) coutvehicle message endl; private: int wheels; /車(chē)輪個(gè)數(shù) float weight; /車(chē)重 ;,14,5.2 向上類(lèi)型轉(zhuǎn)換,class motor_vehicle:

6、public vehicle /vehicle派生類(lèi)motor_vehicle聲明 public: void message() cout motor_ vehicle message endl; private: int passengers; /承載人數(shù) ; class car: public motor_vehicle /motor_ vehicle的派生類(lèi)car聲明 public: void message() coutcar message endl; private: float engine; /發(fā)動(dòng)機(jī)的馬力數(shù) ; class truck: public motor_vehicl

7、e /motor_vehicle的派生類(lèi)truck聲明 public: void message() cout truck message endl; private: int loadpay ; /載重量 ;,15,5.2 向上類(lèi)型轉(zhuǎn)換,int main() vehicle v,*p;/聲明vehicle類(lèi)對(duì)象和基類(lèi)指針p motor_vehicle m; /聲明motor_ vehicle類(lèi)對(duì)象 car c; /聲明car類(lèi)對(duì)象 truck t; /聲明truck類(lèi)對(duì)象 p= ,16,5.4 實(shí)現(xiàn)功能晚綁定虛函數(shù),C+規(guī)定,如果在派生類(lèi)中,沒(méi)有用virtual顯式地給出虛函數(shù)聲明,這時(shí)系統(tǒng)

8、就會(huì)遵循以下的規(guī)則來(lái)判斷一個(gè)成員函數(shù)是不是虛函數(shù): (1)該函數(shù)與基類(lèi)的虛函數(shù)有相同的名稱。 (2)該函數(shù)與基類(lèi)的虛函數(shù)有相同的參數(shù)個(gè)數(shù)及相同的對(duì)應(yīng)參數(shù)類(lèi)型。 (3)該函數(shù)與基類(lèi)的虛函數(shù)有相同的返回類(lèi)型或者滿足賦值兼容規(guī)則的指針、引用型的返回類(lèi)型。,17,5.4 實(shí)現(xiàn)功能晚綁定虛函數(shù),說(shuō)明: 通過(guò)定義虛函數(shù)來(lái)使用C+提供的多態(tài)性機(jī)制時(shí),派生類(lèi)應(yīng)該從它的基類(lèi)公用派生。之所以有這個(gè)要求,是因?yàn)槲覀兪窃谫x值兼容規(guī)則的基礎(chǔ)上來(lái)使用虛函數(shù)的,而賦值兼容規(guī)則成立的前提條件是派生類(lèi)從其基類(lèi)公用派生。 必須首先在基類(lèi)中定義虛函數(shù)。由于“基類(lèi)”與“派生類(lèi)”是相對(duì)的,因此,這項(xiàng)說(shuō)明并不表明必須在類(lèi)等級(jí)的最高層類(lèi)中

9、聲明虛函數(shù)。在實(shí)際應(yīng)用中,應(yīng)該在類(lèi)等級(jí)內(nèi)需要具有動(dòng)態(tài)多態(tài)性的幾個(gè)層次中的最高層類(lèi)內(nèi)首先聲明虛函數(shù)。 在派生類(lèi)對(duì)基類(lèi)中聲明的虛函數(shù)進(jìn)行重新定義時(shí),關(guān)鍵字virtual可以寫(xiě)也可以不寫(xiě)。但為了增強(qiáng)程序的可讀性,最好在對(duì)派生類(lèi)的虛函數(shù)進(jìn)行重新定義時(shí)也加上關(guān)鍵字virtual。 如果在派生類(lèi)中沒(méi)有對(duì)基類(lèi)的虛函數(shù)重新定義,則派生類(lèi)簡(jiǎn)單地繼承其直接基類(lèi)的虛函數(shù)。 雖然使用對(duì)象名和點(diǎn)運(yùn)算符的方式也可以調(diào)用虛函數(shù),例如語(yǔ)句:c.message (); 可以調(diào)用虛函數(shù)car: message () 。但是這種調(diào)用在編譯時(shí)進(jìn)行的是功能早綁定,它沒(méi)有充分利用虛函數(shù)的特性。只有通過(guò)基類(lèi)指針或引用訪問(wèn)虛函數(shù)時(shí)才能獲得運(yùn)

10、行時(shí)的多態(tài)性。,18,5.4 實(shí)現(xiàn)功能晚綁定虛函數(shù),一個(gè)虛函數(shù)無(wú)論被公用繼承多少次,它仍然保持其虛函數(shù)的特性。 虛函數(shù)必須是其所在類(lèi)的成員函數(shù),而不能是友元函數(shù),也不能是靜態(tài)成員函數(shù),因?yàn)樘摵瘮?shù)調(diào)用要靠特定的對(duì)象來(lái)決定該激活哪個(gè)函數(shù)。但是虛函數(shù)可以在另一個(gè)類(lèi)中被聲明為友元函數(shù)。 內(nèi)聯(lián)函數(shù)不能是虛函數(shù),因?yàn)閮?nèi)聯(lián)函數(shù)是不能在運(yùn)行中動(dòng)態(tài)確定其位置的。即使虛函數(shù)在類(lèi)的內(nèi)部定義,編譯時(shí)仍將其看作是非內(nèi)聯(lián)的。 構(gòu)造函數(shù)不能是虛函數(shù)。因?yàn)樘摵瘮?shù)作為運(yùn)行過(guò)程中多態(tài)的基礎(chǔ),主要是針對(duì)對(duì)象的,而構(gòu)造函數(shù)是在對(duì)象產(chǎn)生之前運(yùn)行的,因此虛構(gòu)造函數(shù)是沒(méi)有意義的。 析構(gòu)函數(shù)可以是虛函數(shù),而且通常說(shuō)明為虛函數(shù)。,19,5.4

11、 實(shí)現(xiàn)功能晚綁定虛函數(shù),在析構(gòu)函數(shù)前面加上關(guān)鍵字virtual進(jìn)行說(shuō)明,則稱該析構(gòu)函數(shù)為虛析構(gòu)函數(shù)。虛析構(gòu)函數(shù)的聲明語(yǔ)法為: virtual 類(lèi)名();,20,5.2 向上類(lèi)型轉(zhuǎn)換,【例5-4】 在交通工具類(lèi)vehicle中使用虛析構(gòu)函數(shù)。 #include using namespace std; class vehicle /基類(lèi)vehicle聲明 public: vehicle () /構(gòu)造函數(shù) virtual vehicle () /虛析構(gòu)函數(shù) coutvehicle : vehicle() endl; private: int wheels; float weight; class

12、motor_vehicle:public vehicle /聲明vehicle的公用派生類(lèi)motor_ vehicle public: motor_vehicle () /派生類(lèi)構(gòu)造函數(shù) motor_vehicle () /派生類(lèi)析構(gòu)函數(shù) coutmotor_ vehicle : motor_ vehicle() endl; private: int passengers; int main() vehicle *p; /聲明vehicle類(lèi)指針p p=new motor_vehicle; delete p; return 0; ,21,5.4 實(shí)現(xiàn)功能晚綁定虛函數(shù),在一個(gè)派生類(lèi)中重新定義基類(lèi)

13、的虛函數(shù)不同于一般的函數(shù)重載: 函數(shù)重載處理的是同一層次上的同名函數(shù)問(wèn)題,而虛函數(shù)處理的是同一類(lèi)族中不同派生層次上的同名函數(shù)問(wèn)題,前者是橫向重載,后者可以理解為縱向重載。但與重載不同的是: 同一類(lèi)族的虛函數(shù)的首部是相同的,而函數(shù)重載時(shí)函數(shù)的首部是不同的(參數(shù)個(gè)數(shù)或類(lèi)型不同)。 重載函數(shù)可以是成員函數(shù)或普通函數(shù),而虛函數(shù)只能是成員函數(shù); 重載函數(shù)的調(diào)用是以所傳遞參數(shù)序列的差別作為調(diào)用不同函數(shù)的依據(jù);虛函數(shù)是根據(jù)對(duì)象的不同去調(diào)用不同類(lèi)的虛函數(shù); 虛函數(shù)在運(yùn)行時(shí)表現(xiàn)出多態(tài)功能,這是C+的精髓;而重載函數(shù)則在編譯時(shí)表現(xiàn)出多態(tài)性。,22,5.5 純虛函數(shù)和抽象類(lèi),純虛函數(shù)是一個(gè)在基類(lèi)中說(shuō)明的虛函數(shù),它在

14、該基類(lèi)中沒(méi)有定義,但要求在它的派生類(lèi)中必須定義自己的版本,或重新說(shuō)明為純虛函數(shù)。 純虛函數(shù)的定義形式如下: class 類(lèi)名 virtual 函數(shù)類(lèi)型 函數(shù)名(參數(shù)表)=0; ;,23,5.2 向上類(lèi)型轉(zhuǎn)換,【例5-5】定義一個(gè)公共基類(lèi)Shape,它表示一個(gè)封閉平面幾何圖形。然后,從Shape類(lèi)派生出三角形類(lèi)Trianglet、矩形類(lèi)Rectangle和圓類(lèi)Circle,在基類(lèi)中定義純虛函數(shù)show()和area(),分別用于顯示圖形信息和求相應(yīng)圖形的面積,并在派生類(lèi)中根據(jù)不同的圖形實(shí)現(xiàn)相應(yīng)的函數(shù)。要求實(shí)現(xiàn)運(yùn)行時(shí)的多態(tài)性。 #include #include using namespace s

15、td; const double PI=3.1415926535; class Shape/形狀類(lèi) public: virtual void show()=0; virtual double area()=0; ;,24,5.2 向上類(lèi)型轉(zhuǎn)換,class Rectangle:public Shape/矩形類(lèi) public: Rectangle()length=0; width=0; Rectangle(double len, double wid) length= len;width = wid; double area()return length*width; /求面積 void show

16、() coutlength=lengthtwidth=widthendl; private: double length, width; ; /長(zhǎng)寬 class Circle :public Shape/圓類(lèi) public: Circle()radius = 0; Circle(double r)radius = r; double area()return PI*radius*radius; /求面積 void show()coutradius=radiusendl; private: double radius;,25,5.2 向上類(lèi)型轉(zhuǎn)換,class Triangle:public Sh

17、ape/三角形類(lèi) public: Triangle()a=0;b=0;c=0; Triangle(double x,double y,double z)a = x;b = y;c = z; double area()/求面積 double s=(a+b+c)/2.0; return sqrt(s*(s-a)*(s-b)*(s-c); void show() couta=atb=btc=cendl; private: double a, b,c; /三角形三邊長(zhǎng) ;,26,5.2 向上類(lèi)型轉(zhuǎn)換,int main() Shape *s; Circle c(10); Rectangle r(6,8)

18、; Triangle t(3,4,5); c.show();/靜態(tài)多態(tài) coutshow(); coutarea()show(); coutarea()endl; return 0; ,27,5.5 純虛函數(shù)和抽象類(lèi),如果一個(gè)類(lèi)至少有一個(gè)純虛函數(shù),那么就稱該類(lèi)為抽象類(lèi)。 對(duì)于抽象類(lèi)的使用有以下幾點(diǎn)規(guī)定: (1)由于抽象類(lèi)中至少包含一個(gè)沒(méi)有定義功能的純虛函數(shù)。因此,抽象類(lèi)只能作為其他類(lèi)的基類(lèi)來(lái)使用,不能建立抽象類(lèi)對(duì)象,這只能用來(lái)為派生類(lèi)提供一個(gè)接口規(guī)范,其純虛函數(shù)的實(shí)現(xiàn)由派生類(lèi)給出。 (2)不允許從具體類(lèi)派生出抽象類(lèi),。所謂具體類(lèi),就是不包含純虛函數(shù)的普通類(lèi)。 (3)抽象類(lèi)不能用作參數(shù)類(lèi)型、函數(shù)返回類(lèi)型或顯式轉(zhuǎn)換的類(lèi)型。 (4

溫馨提示

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