類的繼承與多態(tài)性_第1頁
類的繼承與多態(tài)性_第2頁
類的繼承與多態(tài)性_第3頁
類的繼承與多態(tài)性_第4頁
類的繼承與多態(tài)性_第5頁
已閱讀5頁,還剩49頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

類的繼承與多態(tài)性演示文稿目前一頁\總數(shù)五十八頁\編于十二點(diǎn)(優(yōu)選)類的繼承與多態(tài)性目前二頁\總數(shù)五十八頁\編于十二點(diǎn)一、繼承的概念繼承是軟件重用的一種方式。通過繼承建立新類的優(yōu)越性:通過重用已有代碼,提高編程效率,降低軟件開發(fā)成本;更有效地保持共有特性的一致性;提高了系統(tǒng)的可維護(hù)性;是實(shí)現(xiàn)多態(tài)性的基礎(chǔ)。被繼承的類稱為“父類”或“基類”;繼承者被稱為“子類”或“派生類”;§9.1類的繼承目前三頁\總數(shù)五十八頁\編于十二點(diǎn)繼承體現(xiàn)了類的“層次”,從層次上來說,就是位于上層的是基類,下層的為派生類;派生類吸收了基類的非private成員,并增添新的性能?;悺⑴缮愂窍鄬Φ?。目前四頁\總數(shù)五十八頁\編于十二點(diǎn)基類與派生類示例基類派生類學(xué)生本科生,研究生形狀圓,三角形,矩形,球體,立方體貸款汽車貸款,住房貸款,抵押貸款雇員教職員工,后勤人員賬戶支票賬戶,儲蓄賬戶一般地,派生類的對象都“是”其基類的一個對象;基類所能表示的對象集合比派生類所表示的對象集合大.eg.矩形類“是”四邊形類,反之不成立.目前五頁\總數(shù)五十八頁\編于十二點(diǎn)單繼承建筑物房屋橋梁紀(jì)念塔平房樓房居民樓辦公樓單繼承:派生類僅由一個基類派生而來目前六頁\總數(shù)五十八頁\編于十二點(diǎn)多繼承EmployeeFacultyStaffAdministratorTeacherAdministratorteacher多重繼承:派生類由多于一個的基類派生而成多級繼承:等于或多于兩個的繼承層次目前七頁\總數(shù)五十八頁\編于十二點(diǎn)二、派生類的定義定義格式:

class<派生類名>:<繼承方式><基類名>

{派生類新定義成員};繼承方式包括:

public/protected/private

分別表示派生類公有繼承基類,

派生類保護(hù)繼承基類,

派生類私有繼承基類.classA{pulbic:A(intaa=0){a=aa;}voidshowA();private:inta;};classB:publicA{public:B(intbb=0){b=bb;}private:intb;};目前八頁\總數(shù)五十八頁\編于十二點(diǎn)聚合VS繼承聚合:B類對象的成員包括A類的一個或多個對象。繼承:B類對象的成員包括A類的成員。classA{pulbic:A(intaa=0){a=aa;}voidshowA();private:inta;};classB:publicA{public:B(intbb=0){b=bb;}private:intb;};classA{pulbic:A(intaa=0){a=aa;}voidshowA();private:inta;};classB{public:B(intbb=0):aa(0){b=bb;}private:intb;

Aaa;};B-b:int+showA(),+B()B-b:int,-aa:A+B()目前九頁\總數(shù)五十八頁\編于十二點(diǎn)派生類成員的構(gòu)成后舉例基類中的私有成員不能被派生類成員直接引用。派生類對象先存儲其基類子對象部分,再存儲新增部分。目前十頁\總數(shù)五十八頁\編于十二點(diǎn)派生類成員和外部對象訪問基類中的私有成員派生類專屬成員使用基類私有成員的方式:①不能直接使用基類中的私有成員;②成員函數(shù)方式:派生類成員函數(shù)需要通過基類提供的公有或保護(hù)成員函數(shù)間接訪問;外部對象通過基類的公有成員函數(shù)使用其私有成員;③友元方式:把派生類定義為基類的友元,則派生類成員可以直接使用基類成員;而派生類對象則可以用友元函數(shù)間接使用基類私有成員.目前十一頁\總數(shù)五十八頁\編于十二點(diǎn)派生類的三種繼承方式公有繼承:除基類的私有成員繼續(xù)為基類的私有成員外,基類的公有成員和保護(hù)成員分別成為派生類的公有成員和保護(hù)成員。私有繼承:除基類的私有成員繼續(xù)為基類的私有成員外,基類的公有成員和保護(hù)成員將成為派生類的私有成員。保護(hù)繼承:除基類的私有成員繼續(xù)為基類的私有成員外,基類的公有成員和保護(hù)成員將成為派生類的保護(hù)成員。目前十二頁\總數(shù)五十八頁\編于十二點(diǎn)繼承方式基類成員public方式派生類內(nèi)/類外對象private方式派生類內(nèi)/類外對象protected方式派生類內(nèi)/類外對象private不可見不可見不可見protected可見/不可見可見/不可見可見/不可見public可見可見/不可見可見/不可見三種繼承方式存取權(quán)限的關(guān)系類內(nèi):指派生類內(nèi)的成員函數(shù)類外:指類外部定義的派生類對象可見:即可以直接訪問(使用)不可見:只能間接訪問目前十三頁\總數(shù)五十八頁\編于十二點(diǎn)繼承成員的訪問屬性---舉例示例

classX{private:inta;protected:intb;public:intc;};classY1:publicX{intd;public:

output(){returnd;}};Y1的構(gòu)成-----

私有:d

保護(hù):b

公有:output(),c不可直接訪問:a(仍屬于基類)目前十四頁\總數(shù)五十八頁\編于十二點(diǎn)繼承成員的訪問屬性---舉例示例classX{private:inta;protected:intb;public:intc;};classY2:protectedX{intd;public:

output(){returnd;}};Y2的構(gòu)成----

私有:d

保護(hù):bc

公有:output()

不可直接訪問:a(仍屬于基類)目前十五頁\總數(shù)五十八頁\編于十二點(diǎn)繼承成員的訪問屬性---舉例示例classX{private:inta;protected:intb;public:intc;};classY3:private

X{intd;public:

output(){returnd;}};Y3的構(gòu)成----

私有:dbc

保護(hù):公有:output()

不可直接訪問:a(仍屬于基類)目前十六頁\總數(shù)五十八頁\編于十二點(diǎn)(1)public繼承方式在public繼承方式下,派生類內(nèi)的成員函數(shù)中可以訪問基類和派生類中的保護(hù)成員,但外部程序中定義的派生類對象不可訪問基類和派生類中的保護(hù)成員。Eg.例題“public繼承”在public繼承方式下,派生類內(nèi)的成員函數(shù)中可以訪問基類和派生類中的保護(hù)成員,但外部程序中定義的派生類對象不可訪問基類和派生類中的保護(hù)成員。Eg.例題“private繼承”(2)private繼承方式目前十七頁\總數(shù)五十八頁\編于十二點(diǎn)Eg.例題“public繼承”#include<isotream.h>classA{private:inta1;protected:inta2;public:inta3;A(intx1,intx2,intx3):A(x1),a2(x2),a3(x3){}~A(){}};classB:publicA{private:intb1;protected:intb2;public:intb3;B(intx1,intx2,intx3,inty1,inty2,inty3):A(x1,x2,x3),b1(y1),b2(y2),b3(y3){}~B(){}voidprint()const;};voidB::print()const{//cout<<“a1=”<<a1<<endl;//非法

cout<<“a2=”<<a2<<endl;cout<<“a3=”<<a3<<endl;cout<<“b1=”<<b1<<endl;cout<<“b2=”<<b2<<endl;cout<<“b3=”<<b3<<endl;}voidshow(B&myB){//cout<<myB.a1<<myB.a2<<endl;//非法

cout<<“a3=”<<myB.a3<<endl;//cout<<myB.b1<<myB.b2<<endl;//非法

cout<<“b3=”<<myB.b3<<endl;目前十八頁\總數(shù)五十八頁\編于十二點(diǎn)Eg.例題“private繼承”#include<isotream.h>classA{private:inta1;protected:inta2;public:inta3;A(intx1,intx2,intx3):A(x1),a2(x2),a3(x3){}~A(){}};classB:privateA{private:intb1;protected:intb2;public:intb3;B(intx1,intx2,intx3,inty1,inty2,inty3):A(x1,x2,x3),b1(y1),b2(y2),b3(y3){}~B(){}voidprint();};voidB::print(){//cout<<“a1=”<<a1<<endl;//非法

cout<<“a2=”<<a2<<“a3=”<<a3<<endl;cout<<“b1=”<<b1<<“b2=”<<b2<<endl;cout<<“b3=”<<b3<<endl;}voidshow(AmyA,B&myB){//cout<<myA.a1<<myA.a2;非法

cout<<myA.a3<<endl;//cout<<“myB.a1<<myB.a2<<endl;//非法

//cout<<“a3=”<<myB.a3<<endl;//非法

//cout<<myB.b1<<myB.b2<<endl;//非法

cout<<“b3=”<<myB.b3<<endl;目前十九頁\總數(shù)五十八頁\編于十二點(diǎn)三、派生類的構(gòu)造函數(shù)繼承關(guān)系中,基類的兩個特殊成員函數(shù)---構(gòu)造函數(shù)和析構(gòu)函數(shù)不能被繼承。因此,派生類的構(gòu)造函數(shù)不僅要初始化派生類中定義的數(shù)據(jù)成員,而且要初始化派生類中的基類子對象(派生類對象中由基類定義的部分稱作基類子對象)?;愖訉ο蟮某跏蓟x值是通過在派生類構(gòu)造函數(shù)中顯式或隱式地調(diào)用基類構(gòu)造函數(shù)實(shí)現(xiàn)的。構(gòu)造函數(shù)的執(zhí)行順序:先執(zhí)行基類構(gòu)造函數(shù),再執(zhí)行派生類構(gòu)造函數(shù)。基類子對象派生類專有部分派生類目前二十頁\總數(shù)五十八頁\編于十二點(diǎn)例1:P267例題classA

{

inta1;

protected:

inta2;

public:

inta3;

A(){a1=a2=a3=0;}

A(intx1,intx2,intx3):a1(x1),a2(x2),a3(x3){}

voidout(){cout<<a1<<‘‘<<a2<<‘‘<<a3<<endl;}

intGeta1(){returna1;}

};返回B類目前二十一頁\總數(shù)五十八頁\編于十二點(diǎn)classB:publicA{

intb1;

protected:

intb2;

public:

intb3;

B(){b1=b2=b3=0;}

B(intx1,intx2,intx3):A(x1,x2,x3)

{b1=x1+1;b2=x2+2;b3=x3+3;}

voidout(){A::out();

cout<<b1<<‘‘<<b2<<‘‘<<b3<<endl;}

intSum(){returnGeta1()*b1+a2*b2+a3*b3;}};隱含調(diào)用A()顯式調(diào)用

A(int,int,int)調(diào)用類A中的無參構(gòu)造函數(shù)返回main()函數(shù)//A類和B類中都有Out(),則用::界定其所屬,若不加則指的是本類成員.調(diào)用類A中的帶參構(gòu)造函數(shù)目前二十二頁\總數(shù)五十八頁\編于十二點(diǎn)

voidmain(){

Bb1,b2(1,2,3);b1.Out();b2.Out();cout<<b1.Sum()<<‘‘<<b2.Sum()<<endl;cout<<sizeof(B)<<endl;}調(diào)用類B中的構(gòu)造函數(shù)初始化對象目前二十三頁\總數(shù)五十八頁\編于十二點(diǎn)四、派生類的析構(gòu)函數(shù)撤銷派生類對象時,系統(tǒng)先自動調(diào)用派生類的析構(gòu)函數(shù),再調(diào)用基類的析構(gòu)函數(shù)。系統(tǒng)對派生類和基類析構(gòu)函數(shù)的自動調(diào)用順序和其對構(gòu)造函數(shù)的調(diào)用順序正好相反。例:類層次中普通析構(gòu)函數(shù)目前二十四頁\總數(shù)五十八頁\編于十二點(diǎn)五、基類和派生類的賦值兼容規(guī)則在滿足公有繼承的限制條件下,C++允許派生類對象到基類對象的自動轉(zhuǎn)換,通常稱為賦值兼容規(guī)則。規(guī)則1:可以用派生類對象為基類對象賦值規(guī)則2:可以用派生類對象初始化基類的引用對象規(guī)則3:可以用基類的指針指向派生類對象eg.賦值兼容規(guī)則eg.類層次中普通析構(gòu)函數(shù)目前二十五頁\總數(shù)五十八頁\編于十二點(diǎn)§9.2多重繼承多級繼承引例:Windows風(fēng)格用戶界面設(shè)計先設(shè)計出窗口類、尺寸類、橫向/縱向滾動條類、按鈕類;用戶界面類將上述各類作為基類,通過多重繼承產(chǎn)生。一、多重繼承時的派生類

1、定義格式:

class派生類名:

[繼承方式1][基類名1],[繼承方式2][基類名2],…{派生類成員定義};注:各基類名不能相同目前二十六頁\總數(shù)五十八頁\編于十二點(diǎn)2、初始化數(shù)據(jù)成員—調(diào)用構(gòu)造函數(shù)1)調(diào)用順序構(gòu)造函數(shù)調(diào)用順序:

(1)初始化第一個基類子對象,即調(diào)用第一個基類的構(gòu)造函數(shù);初始化第二個基類子對象,即調(diào)用第二個基類的構(gòu)造函數(shù);

……

初始化第n個基類子對象,即調(diào)用第n個基類的構(gòu)造函數(shù)。

(2)派生類中若有基類對象作成員,則調(diào)用相應(yīng)基類的構(gòu)造函數(shù)。

(3)最后初始化派生類普通成員。析構(gòu)函數(shù)調(diào)用順序:與構(gòu)造函數(shù)相反。目前二十七頁\總數(shù)五十八頁\編于十二點(diǎn)例:多重繼承時的構(gòu)造函數(shù)的調(diào)用P269說明:派生類初始化成員的順序:

首先對基類子對象成員的初始化,

然后對新增對象成員初始化,

最后對新增非對象成員初始化.注:前兩步必須在構(gòu)造函數(shù)的初值表中給出初值項(xiàng)

(省略時調(diào)用無參構(gòu)造函數(shù));

后一步可以通過初值表,也可以通過函數(shù)體進(jìn)行.目前二十八頁\總數(shù)五十八頁\編于十二點(diǎn)二、多級繼承中的派生類

classA{};classB:publicA{};classC:publicB{};B直接繼承類A,C直接繼承類B,間接繼承類A。eg.P270多級繼承舉例多級繼承時的初始化順序:先執(zhí)行最上層基類的構(gòu)造函數(shù),依次向下執(zhí)行各基類的構(gòu)造函數(shù),最后是當(dāng)前派生類的構(gòu)造函數(shù)對新增成員的初始化.目前二十九頁\總數(shù)五十八頁\編于十二點(diǎn)執(zhí)行C的構(gòu)造函數(shù)前先調(diào)用B1、B2構(gòu)造函數(shù);執(zhí)行B1、B2構(gòu)造函數(shù)前先分別調(diào)用A的構(gòu)造函數(shù)。AB1B2CA為C的公共基類eg.數(shù)據(jù)成員二義性三、混合多繼承中的構(gòu)造函數(shù)classC:publicB1,publicB2{};目前三十頁\總數(shù)五十八頁\編于十二點(diǎn)1、數(shù)據(jù)成員二義性假設(shè)圖中類A有數(shù)據(jù)成員a,則C中有兩個a成員,a是哪個派生類的成員?產(chǎn)生了二義性。解決方法:

(1)加類名分辨符B1::或B2::(2)定義虛基類

eg1.數(shù)據(jù)成員二義性A(a)B1(a,b1)B2(a,b2)C(a,b1,b2,c)四、多繼承中二義性問題的解決目前三十一頁\總數(shù)五十八頁\編于十二點(diǎn)2、函數(shù)成員二義性

B1,B2中都含有print()成員函數(shù),C繼承了B1,B2,則C中有兩個print()函數(shù)。解決方法:加類區(qū)分符::eg2.函數(shù)成員二義性B1(print())B2(print())C目前三十二頁\總數(shù)五十八頁\編于十二點(diǎn)§9.3虛基類消除數(shù)據(jù)成員二義性的兩種方法的區(qū)別:

(1)”類名::”法:消除二義性同時實(shí)現(xiàn)程序設(shè)計的多態(tài)性,但在派生類對象中存在多個公共基類的同名數(shù)據(jù)成員

(2)”虛函數(shù)”法:消除二義性,且在派生類對象中只存在一個公共基類的數(shù)據(jù)成員設(shè)計虛基類:

(1)一個基類有多于一個派生類時,在這些派生類“繼承方式”前加上

virtual關(guān)鍵字。

classB1:virtualpublicAclassB2:virtualpublicA

此時將公共基類A稱為虛基類。AB1B2C目前三十三頁\總數(shù)五十八頁\編于十二點(diǎn)(2)虛基類子對象由最新派生出來的派生類直接初始化。

B1,B2對類A子對象初始化,

C也要對類A子對象初始化。

eg.虛基類注意:對非虛基類,不能在C中對A類子對象初始化。AB1B2C目前三十四頁\總數(shù)五十八頁\編于十二點(diǎn)§9.4類的虛函數(shù)和多態(tài)性對于相同的函數(shù)調(diào)用,依賴每個對象自己做出恰當(dāng)?shù)捻憫?yīng),這是多態(tài)性的關(guān)鍵思想。多態(tài)性(polymorphism):不同對象在接收同樣的消息時,所做出的響應(yīng)不同。多態(tài)性的實(shí)現(xiàn)依賴于動態(tài)聯(lián)編。指調(diào)用名稱相同的成員函數(shù)指不同派生類的成員函數(shù)目前三十五頁\總數(shù)五十八頁\編于十二點(diǎn)一、滯后聯(lián)編

聯(lián)編:指一個標(biāo)識符名和一個存儲地址聯(lián)系在一起的過程。

1、靜態(tài)聯(lián)編(早期聯(lián)編)指:聯(lián)編工作出現(xiàn)在編譯連接階段,因?yàn)檫@種聯(lián)編過程在程序開始運(yùn)行之前完成,所以又稱早期聯(lián)編。在編譯時就解決了程序中的操作調(diào)用與執(zhí)行該操作代碼間的關(guān)系,確定這種關(guān)系又被稱為束定,因此,靜態(tài)聯(lián)編又稱為靜態(tài)束定。

2、動態(tài)聯(lián)編(滯后聯(lián)編)指:在程序執(zhí)行時進(jìn)行的聯(lián)編,稱動態(tài)聯(lián)編,或稱動態(tài)束定,又叫滯后聯(lián)編。動態(tài)聯(lián)編時在不同階段被束定的類的對象將是不同的。動態(tài)聯(lián)編的實(shí)現(xiàn):C++中,在虛函數(shù)的支持下實(shí)現(xiàn)。目前三十六頁\總數(shù)五十八頁\編于十二點(diǎn)二、虛函數(shù)的定義1、定義:virtual成員函數(shù)原型;2、注意:

(1)只有在類的繼承關(guān)系中才存在虛函數(shù)。在基類中聲明某成員函數(shù)為虛函數(shù),則派生類中(名字、參數(shù)個數(shù)、參數(shù)類型和返回值類型都)相同的成員函數(shù)都視作虛函數(shù)。

(2)使用虛函數(shù)須利用賦值兼容規(guī)則,要求public繼承方式。

(3)多態(tài)性使我們編寫的程序在處理同一個類層次結(jié)構(gòu)下類的對象時好像它們是基類的所有對象一樣。目前三十七頁\總數(shù)五十八頁\編于十二點(diǎn)三、虛函數(shù)的使用多態(tài)性是利用基類的指針句柄和基類的引用句柄,而不是利用名字句柄。實(shí)現(xiàn)多態(tài)的步驟:

(1)定義基類指針

(2)用該指針指向基類或派生類對象

(3)當(dāng)程序發(fā)送虛函數(shù)消息時:若指針指向基類對象,系統(tǒng)調(diào)用基類成員函數(shù),若指針指向派生類對象,系統(tǒng)調(diào)用派生類成員函數(shù)。

(4)若沒有步驟(2)中賦值,系統(tǒng)按早期聯(lián)編方式調(diào)用基類成員函數(shù)。目前三十八頁\總數(shù)五十八頁\編于十二點(diǎn)classX1{intx;public:X1(intxx=0){x=xx;}virtualvoidOutput(){cout<<“x=“<<x<<endl;}};classY1:publicX1{inty;public:Y1(intxx=0,intyy=0):X1(xx){y=yy;}virtualvoidOutput(){X1::Output();cout<<“y=“<<y<<endl;}};可以去掉這里的virtual例:虛函數(shù)目前三十九頁\總數(shù)五十八頁\編于十二點(diǎn)classZ1:publicX1{intz;public:Z1(intxx=0,intzz=0):X1(xx){z=zz;}virtualvoidOutput(){X1::Output();cout<<“z=“<<z<<endl;}};voidmain(){X1a(5);Y1b(6,7);Z1c(8,9);X1*p[3]={&a,&b,&c};for(inti=0;i<3;i++){p[i]->Output();cout<<endl;}}結(jié)論:定義了虛函數(shù)后,通過基類指針調(diào)用虛函數(shù)時,實(shí)際被調(diào)用的是指針?biāo)笇ο髢?nèi)的函數(shù);結(jié)果:x=5

x=6

Y=7

x=8

z=9不定義虛函數(shù)時的結(jié)果:x=5

x=6

x=8基類子對象派生類專有部分派生類目前四十頁\總數(shù)五十八頁\編于十二點(diǎn)虛函數(shù)的調(diào)用說明:使用基類指針指向其派生類的對象;相同的調(diào)用方式實(shí)際上能夠調(diào)用一組中的任何一個派生類中的虛函數(shù),即是多態(tài)性。由于被實(shí)際調(diào)用的函數(shù)是在運(yùn)行時確定的,因此稱為動態(tài)綁定虛函數(shù)的使用限制:只能通過指針或引用調(diào)用虛函數(shù);如果用普通對象名調(diào)用虛函數(shù),將釆用靜態(tài)聯(lián)編方式;虛函數(shù)定義時,函數(shù)名、返回類型、參數(shù)類型、個數(shù)和順序與基類中的函數(shù)定義應(yīng)完全一致。(不同于重載函數(shù))構(gòu)造函數(shù)不能定義為虛函數(shù),但析構(gòu)函數(shù)可以。目前四十一頁\總數(shù)五十八頁\編于十二點(diǎn)voidmain(){Bb;

b.act2();}考慮:

1、程序結(jié)果是什么?

2、如果將A中act2()實(shí)現(xiàn)為:

voidA::act2(){this->act1();}

結(jié)果如何?

3、如果將A中act1()前的virtual

去掉,結(jié)果如何?例:#include<iostream.h>classA{public:

virtualvoidact1();voidact2(){act1();}};voidA::act1(){cout<<“A::act1()called.”<<endl;}classB:publicA{public:

voidact1();};voidB::act1(){cout<<“B::act1()called.”<<endl;}B::act1()called.B::act1()called.A::act1()called.可以由成員函數(shù)調(diào)用虛函數(shù)目前四十二頁\總數(shù)五十八頁\編于十二點(diǎn)四、構(gòu)造函數(shù)中調(diào)用虛函數(shù)#include<iostream.h>classA{public:A(){}virtualvoidf(){cout<<“A::f()called.\n”;}};classB:publicA{public:B(){f();}voidg(){f();}};classC:publicB{public:C(){}virtualvoidf(){cout<<“C::f()called.\n”;}};voidmain(){Cc;c.g();}結(jié)果:A::f()called.C::f()called.結(jié)論:構(gòu)造函數(shù)中調(diào)用虛函數(shù)時,釆用靜態(tài)聯(lián)編,即構(gòu)造函數(shù)調(diào)用的虛函數(shù)是自己類中實(shí)現(xiàn)的虛函數(shù),如果自己類中沒有實(shí)現(xiàn)這個虛函數(shù),則調(diào)用基類中的虛函數(shù)。目前四十三頁\總數(shù)五十八頁\編于十二點(diǎn)例:定義普通析構(gòu)函數(shù)#include<iostream.h>classAA{inti;public:AA(intn):i(n){}~AA(){cout<<“AA“<<endl;}};classBB:publicAA{char*p;public:BB(intn,char*s):AA(n){p=newchar[strlen(s)+1];strcpy(p,s);}~BB(){deletep;cout<<“BB”<<endl;}};voidmain(){AA*p=newBB(5,”abcd”);

deletep;

};結(jié)果:AA普通析構(gòu)函數(shù)在使用delete刪除一個對象時,是靜態(tài)聯(lián)編,關(guān)聯(lián)的只是基類的析構(gòu)函數(shù)。五、虛析構(gòu)函數(shù)目前四十四頁\總數(shù)五十八頁\編于十二點(diǎn)#include<iostream.h>classAA{inti;public:AA(intn):i(n){}virtual~AA(){cout<<“AA“<<endl;}};classBB:publicAA{char*p;public:BB(intn,char*s):AA(n){p=newchar[strlen(s)+1];strcpy(p,s);}~BB(){deletep;cout<<“BB”<<endl;}};voidmain(){AA*p=newBB(5,”abcd”);

deletep;

};結(jié)果:BB

AA虛析構(gòu)函數(shù)的目的在于使用delete刪除一個對象時,是動態(tài)聯(lián)編,關(guān)聯(lián)的是子類的析構(gòu)函數(shù)。例:定義虛析構(gòu)函數(shù)目前四十五頁\總數(shù)五十八頁\編于十二點(diǎn)六、純虛函數(shù)與抽象類軟件使用者:某軟件只要用到一些具體事物的類(如:Sphere,Cylinder,Cone類)

軟件設(shè)計者:增加一個更抽象的基類效果更好(代碼重用)(如:Circle類)--某些成員函數(shù)在基類中的實(shí)現(xiàn)變得沒意義(如:Area(),Volume()函數(shù)),但其聲明仍有意義。

問題:能否將這樣的成員函數(shù)在基類中只作聲明,而其實(shí)現(xiàn)留給派生類呢?

用純虛函數(shù)將基類改造為抽象類目前四十六頁\總數(shù)五十八頁\編于十二點(diǎn)1、純虛函數(shù)定義:

virtual返回類型函數(shù)名(參數(shù)表)=0純虛函數(shù)在基類中聲明,具體實(shí)現(xiàn)在派生類中。2、抽象類包含純虛函數(shù)的類稱為抽象類。抽象類為其所有子類提供了統(tǒng)一的操作界面。說明:抽象類不能實(shí)例化,即不能聲明抽象類對象;抽象類只作為基類被繼承,無派生類的抽象類無意義可定義指向抽象類的指針或引用,它們必然指向派生類對象,從而實(shí)現(xiàn)多態(tài)性。目前四十七頁\總數(shù)五十八頁\編于十二點(diǎn)例:純虛函數(shù)與抽象類classShape{public:

virtualdoublearea()=0;};classPoint{doublex,y;public:Point(doublex0=0.0,doubley0=0.0):x(x0),y(y0){}doublegetX(){returnx;}doublegetY(){returny;}};目前四十八頁\總數(shù)五十八頁\編于十二點(diǎn)classRectAngle:publicShape{Pointul;//左下角頂點(diǎn)

Pointdr;//右上角頂點(diǎn)public:RectAngle(Pointp1,Pointp2):ul(p1),dr(p2){}

virtualdoublearea(){

return(dr.getX()-ul.getX())*(dr.getY()-ul.getY());

}PointgetUpleft(){returnul;}PointgetDownright(){returndr;}};目前四十九頁\總數(shù)五十八頁\編于十二點(diǎn)classCircle:publicShape{Pointcen;//圓心

doublerad;//半徑public:Circle(Pointc,doubler):cen(c),rad(r){}

virtualdoublearea(){return3.1415926*rad*rad;}PointgetCenter(){returncen;}doublegetRadius(){returnrad;}};voidshowArea(Shape&s){cout<<s.area();}voidmain(){RectAngle

r(Point(2.0,2.0),Point(8.0,8.0));

showArea(r);cout<<endl;Circlec(Point(8,8),4);

showArea(c);}通過調(diào)用showArea()這同一動作,計算出不同形狀的面積,即同一消息,不同響應(yīng)-----多態(tài)性。目前五十頁\總數(shù)五十八頁\編于十二點(diǎn)類非static數(shù)據(jù)成員函數(shù)成員對象1非static數(shù)據(jù)成員對象2非static數(shù)據(jù)成員對象n非static數(shù)據(jù)成員目前五十一頁\總數(shù)五十八頁\編于十二點(diǎn)類數(shù)據(jù)成員函數(shù)成員static數(shù)據(jù)成員對象1對象2對象n對象3目前五十二頁\總數(shù)五十八頁\編于十二點(diǎn)§9.5類的靜態(tài)成員在類成員聲明前加上static修飾即把該成員聲明為該類的靜態(tài)成員;static數(shù)據(jù)成員靜態(tài)數(shù)據(jù)成員必須在定義第一個對象之前作為靜態(tài)變量加以定義并初始化;靜態(tài)函數(shù)成員沒有this指針,只能直接訪問類中的靜態(tài)成員(如要訪問類中非靜態(tài)成員,必須借助對象名或指向?qū)ο蟮闹羔槪?。靜態(tài)成員不能說明為虛函數(shù)。一般地,每個對象都存放有其所屬類中所有成員的拷貝.

非static數(shù)據(jù)成員但有時希望程序中的同類對象共享某個成員,解決方法:(一)將要共享成員說明為全局變量---破壞封裝性(二)將要共享成員說明成類的靜態(tài)成員---較好目前五十三頁\總數(shù)五十八頁\編于十二點(diǎn)例1:類的靜態(tài)數(shù)據(jù)成員classXX{inta;public:

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論