第七章繼承與派生_第1頁
第七章繼承與派生_第2頁
第七章繼承與派生_第3頁
第七章繼承與派生_第4頁
第七章繼承與派生_第5頁
已閱讀5頁,還剩38頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第七章:繼承與派生第七章:繼承與派生類的繼承與派生類的繼承與派生 保持已有類的特性而構(gòu)造新類的過程稱保持已有類的特性而構(gòu)造新類的過程稱為為繼承繼承。 在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)生新類的過程稱為生新類的過程稱為派生派生。 被繼承的已有類稱為被繼承的已有類稱為基類基類(或父類)。(或父類)。 派生出的新類稱為派生出的新類稱為派生類派生類。第七章:繼承與派生第七章:繼承與派生 類的繼承與派生類的繼承與派生 類成員的訪問控制類成員的訪問控制 類型兼容規(guī)則類型兼容規(guī)則 派生類的構(gòu)造函數(shù)、析構(gòu)函數(shù)派生類的構(gòu)造函數(shù)、析構(gòu)函數(shù) 派生類成員的標(biāo)識與訪問派生類成員的標(biāo)識與

2、訪問第一節(jié):類的繼承與派生第一節(jié):類的繼承與派生工具車轎車面包車小汽車卡車旅行車汽車汽車交通工具交通工具單繼承單繼承多重派生多重派生多層派生多層派生第一節(jié):類的繼承與派生第一節(jié):類的繼承與派生兼職技術(shù)人員銷售經(jīng)理管理人員銷售人員雇員多繼承多繼承多重派生多重派生多層派生多層派生繼承與派生的目的繼承與派生的目的 繼承的目的:實現(xiàn)代碼重用。繼承的目的:實現(xiàn)代碼重用。 派生的目的:當(dāng)新的問題出現(xiàn),原有程派生的目的:當(dāng)新的問題出現(xiàn),原有程序無法解決(或不能完全解決)時,需序無法解決(或不能完全解決)時,需要對原有程序進(jìn)行改造。要對原有程序進(jìn)行改造。二、派生類的定義二、派生類的定義class 派生類名:派

3、生類名:繼承方式繼承方式 基類名基類名 成員聲明;成員聲明;class 派生類名:派生類名:繼承方式繼承方式1 基類名基類名1,繼承方式繼承方式2 基類名基類名2,. 成員聲明;成員聲明;注意:每一個注意:每一個“繼承方式繼承方式”,只用于限制對緊隨其后之,只用于限制對緊隨其后之基類的繼承?;惖睦^承。繼承方式繼承方式 三種繼承方式三種繼承方式 公有繼承(公有繼承(public) 私有繼承(私有繼承(private) 保護(hù)繼承(保護(hù)繼承(protected) 不同繼承方式的影響主要體現(xiàn)在:不同繼承方式的影響主要體現(xiàn)在: 派生類派生類成員對基類成員的訪問權(quán)限對基類成員的訪問權(quán)限 通過派生類通過派

4、生類對象對基類成員的訪問權(quán)限對基類成員的訪問權(quán)限三、派生類生成過程三、派生類生成過程 派生類的生成過程包括派生類的生成過程包括三三個步驟:個步驟: 吸收基類成員:派生類吸收基類中吸收基類成員:派生類吸收基類中除構(gòu)造函除構(gòu)造函數(shù)和析構(gòu)函數(shù)數(shù)和析構(gòu)函數(shù)之外的所有成員。之外的所有成員。 改造基類成員改造基類成員 基類成員的訪問控制問題基類成員的訪問控制問題 基類數(shù)據(jù)或函數(shù)成員的覆蓋基類數(shù)據(jù)或函數(shù)成員的覆蓋(同名覆蓋同名覆蓋:派生類中有一個與基類中相同名稱:派生類中有一個與基類中相同名稱的函數(shù)。)的函數(shù)。) 添加新的成員添加新的成員class employeeprotected:char name20

5、;/姓名int individualEmpNo;/個人編號int grade;/級別float accumPay;/月薪總額static int employeeNo;/本公司職員編號目前最大值public:employee();/構(gòu)造函數(shù)employee();/析構(gòu)函數(shù)void pay();/計算月薪函數(shù)void promote(int); /升級函數(shù)void SetName(char *); /設(shè)置姓名函數(shù)char * GetName(); /提取姓名函數(shù)int GetindividualEmpNo(); /提取編號函數(shù)int Getgrade(); /提取級別函數(shù)float Getacc

6、umPay(); /提取月薪函數(shù);class technician:public employee/兼職技術(shù)人員類private:float hourlyRate;/每小時酬金int workHours;/當(dāng)月工作時數(shù)public:technician();/構(gòu)造函數(shù)void SetworkHours(int wh); /設(shè)置工作時數(shù)void pay();/計算月薪函數(shù);第二節(jié):訪問控制第二節(jié):訪問控制 訪問控制主要關(guān)注兩個問題:訪問控制主要關(guān)注兩個問題: 派生類中的派生類中的新增成員新增成員訪問從基類繼承的成員。訪問從基類繼承的成員。 派生類的派生類的對象對象訪問從基類繼承的成員。訪問從基類

7、繼承的成員。公有繼承公有繼承 基類的基類的public和和protected成員的訪問屬成員的訪問屬性在派生類中性在派生類中保持不變保持不變,但,但基類的基類的private成員成員不可不可直接直接訪問訪問。 派生類中的成員函數(shù)可以直接訪問基類中的派生類中的成員函數(shù)可以直接訪問基類中的public和和protected成員,但不能直接訪問成員,但不能直接訪問基類的基類的private成員。成員。 通過派生類的對象只能訪問基類的通過派生類的對象只能訪問基類的public成成員。員。class Point/基類Point類的聲明public:/公有函數(shù)成員void InitP(float xx=0

8、, float yy=0) X=xx;Y=yy;void Move(float xOff, float yOff) X+=xOff;Y+=yOff;float GetX() return X;float GetY() return Y;private:/私有數(shù)據(jù)成員float X,Y;class Rectangle: public Point /派生類聲明部分public:/新增公有函數(shù)成員void InitR(float x, float y, float w, float h)InitP(x,y);W=w;H=h;/調(diào)用基類公有成員函數(shù)float GetH() return H;float

9、 GetW() return W;private:/新增私有數(shù)據(jù)成員float W,H;#include#include#include rectangle.husing namespace std;void main()Rectangle rect;/聲明Rectangle類的對象rect.InitR(2,3,20,10);/設(shè)置矩形的數(shù)據(jù)rect.Move(3,2);/移動矩形位置coutThe data of rect(X,Y,W,H):endl;coutrect.GetX(),/輸出矩形的特征參數(shù) rect.GetY(), rect.GetW(), rect.GetH()endl;私有

10、繼承私有繼承 基類的基類的public和和protected成員都以成員都以private身份出現(xiàn)在派生類中,但基類的身份出現(xiàn)在派生類中,但基類的private成員成員不可直接訪問不可直接訪問。 派生類中的成員函數(shù)可以直接訪問基類中的派生類中的成員函數(shù)可以直接訪問基類中的public和和protected成員,但不能直接訪問成員,但不能直接訪問基類的基類的private成員。成員。 通過派生類的對象不能直接訪問基類中的任通過派生類的對象不能直接訪問基類中的任何成員。何成員。class Point/基類Point類的聲明public:/公有函數(shù)成員void InitP(float xx=0, f

11、loat yy=0) X=xx;Y=yy;void Move(float xOff, float yOff) X+=xOff;Y+=yOff;float GetX() return X;float GetY() return Y;private:float X,Y;class Rectangle: private Point/派生類聲明派生類聲明public: /新增外部接口新增外部接口void InitR(float x, float y, float w, float h)InitP(x,y);W=w;H=h;/訪問基類公訪問基類公有成員有成員void Move(float xOff, f

12、loat yOff) Point:Move(xOff,yOff);float GetX() return Point:GetX();float GetY() return Point:GetY();float GetH() return H;float GetW() return W;private: /新增私有數(shù)據(jù)新增私有數(shù)據(jù)float W,H;int main() /通過派生類對象只能訪通過派生類對象只能訪問本類成員問本類成員 Rectangle rect;rect.InitR(2,3,20,10);rect.Move(3,2);coutrect.GetX(), rect.GetY(),r

13、ect.GetH(),rect.GetW()endl;return 0;保護(hù)繼承保護(hù)繼承 基類的基類的public和和protected成員都以成員都以protected身份出現(xiàn)身份出現(xiàn)在派生類中,但基類在派生類中,但基類的的private成員成員不可直接訪問不可直接訪問。 派生類中的成員函數(shù)可以直接訪問基類中的派生類中的成員函數(shù)可以直接訪問基類中的public和和protected成員,但不能直接訪問成員,但不能直接訪問基類的基類的private成員。成員。 通過派生類的對象不能直接訪問基類中的任通過派生類的對象不能直接訪問基類中的任何成員何成員。保護(hù)繼承的特點和作用保護(hù)繼承的特點和作用 對

14、對派生類對象派生類對象來說,它與來說,它與 private 成員成員的性質(zhì)相同。的性質(zhì)相同。 對對派生類派生類來說,它與來說,它與 public 成員的性質(zhì)成員的性質(zhì)相同。相同。 既實現(xiàn)了數(shù)據(jù)隱藏,又方便繼承,實現(xiàn)既實現(xiàn)了數(shù)據(jù)隱藏,又方便繼承,實現(xiàn)代碼重用。代碼重用。protected 成員舉例成員舉例class A protected: int x;int main() A a; a.x=5; /錯誤錯誤class A protected: int x;class B: public A public: void Function();void B:Function() x=5; /正確正確

15、class A public: void setA(int); void showA(); private: int a;class B public: void setB(int); void showB();private: int b;class C : public A, private B public: void setC(int, int, int); void showC(); private: int c;void A:setA(int x) a=x; void B:setB(int x) b=x; void C:setC(int x, int y, int z) /派生類成

16、員直接訪問基類的 /公有成員 setA(x); setB(y); c=z;int main() C obj; obj.setA(5); obj.showA(); obj.setC(6,7,9); obj.showC();/ obj.setB(6); 錯誤/ obj.showB(); 錯誤 return 0;三、類型兼容規(guī)則三、類型兼容規(guī)則 一個一個公有派生類的對象公有派生類的對象在使用上可以被當(dāng)作在使用上可以被當(dāng)作基類基類的對象的對象,反之則禁止。具體表現(xiàn)在:,反之則禁止。具體表現(xiàn)在:Class BClass D:public B/D為為B的公有派生類的公有派生類B b1,*pb1;D d1;

17、 派生類的對象可以被賦值給基類對象。派生類的對象可以被賦值給基類對象。b1=d1 派生類的對象可以初始化基類的引用。派生類的對象可以初始化基類的引用。B &bb=d1 指向基類的指針也可以指向派生類。指向基類的指針也可以指向派生類。 pb1=&d1 替代之后,派生類對象可以作為基類的對象使用,替代之后,派生類對象可以作為基類的對象使用,但但只能使用從基類繼承的成員只能使用從基類繼承的成員。#include using namespace std;class B0 /基類B0聲明public:void display()coutB0:display()endl;/公有成員函數(shù);class B1:

18、 public B0/公有派生類B1聲明public:void display()coutB1:display()endl;/公有成員函數(shù);class D1: public B1/公有派生類D1聲明public:void display()coutD1:display()display();/對象指針-成員名void main()/主函數(shù)B0 b0;/聲明B0類對象B1 b1;/聲明B1類對象D1 d1;/聲明D1類對象B0 *p;/聲明B0類指針p=&b0;/B0類指針指向B0類對象fun(p);p=&b1;/B0類指針指向B1類對象fun(p);p=&d1;/B0類指針指向D1類對象fun

19、(p); b1.display(); d1.display();四、派生類的構(gòu)造和析構(gòu)函數(shù)四、派生類的構(gòu)造和析構(gòu)函數(shù) 基類的構(gòu)造函數(shù)不被繼承,派生類中需基類的構(gòu)造函數(shù)不被繼承,派生類中需要聲明自己的構(gòu)造函數(shù)。要聲明自己的構(gòu)造函數(shù)。 構(gòu)造派生類的對象時,需對構(gòu)造派生類的對象時,需對基類數(shù)據(jù)成基類數(shù)據(jù)成員員、新增數(shù)據(jù)成員新增數(shù)據(jù)成員和和內(nèi)嵌成員對象的數(shù)內(nèi)嵌成員對象的數(shù)據(jù)成員據(jù)成員進(jìn)行初始化。進(jìn)行初始化。派生類構(gòu)造函數(shù)派生類構(gòu)造函數(shù)派生類名派生類名:派生類名派生類名(參數(shù)總表參數(shù)總表):基類名基類名1(參數(shù)表參數(shù)表1),基類名基類名n(參數(shù)表(參數(shù)表n),),內(nèi)嵌對象名內(nèi)嵌對象名1(內(nèi)嵌對象參數(shù)(內(nèi)

20、嵌對象參數(shù)表表1),),內(nèi)嵌對象名,內(nèi)嵌對象名m(內(nèi)嵌對象參數(shù)表(內(nèi)嵌對象參數(shù)表m)派生類新增成員的初始化語句;派生類新增成員的初始化語句; 聲明構(gòu)造函數(shù)時,只需要對本類中新增成員進(jìn)行初始聲明構(gòu)造函數(shù)時,只需要對本類中新增成員進(jìn)行初始化。對繼承來的化。對繼承來的基類數(shù)據(jù)成員的初始化基類數(shù)據(jù)成員的初始化,自動調(diào)用基,自動調(diào)用基類構(gòu)造函數(shù)完成。對類構(gòu)造函數(shù)完成。對成員對象數(shù)據(jù)成員的初始化成員對象數(shù)據(jù)成員的初始化,由,由內(nèi)嵌對象的構(gòu)造函數(shù)完成。內(nèi)嵌對象的構(gòu)造函數(shù)完成。派生類構(gòu)造函數(shù)派生類構(gòu)造函數(shù) 派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)和內(nèi)派生類的構(gòu)造函數(shù)需要給基類的構(gòu)造函數(shù)和內(nèi)嵌對象的構(gòu)造函數(shù)傳遞參數(shù)

21、。嵌對象的構(gòu)造函數(shù)傳遞參數(shù)。 當(dāng)基類中當(dāng)基類中聲明有默認(rèn)形式的構(gòu)造函數(shù)或未聲明構(gòu)造聲明有默認(rèn)形式的構(gòu)造函數(shù)或未聲明構(gòu)造函數(shù)時函數(shù)時,派生類構(gòu)造函數(shù)可以不向基類構(gòu)造函數(shù)傳,派生類構(gòu)造函數(shù)可以不向基類構(gòu)造函數(shù)傳遞參數(shù)。遞參數(shù)。 若基類中未聲明構(gòu)造函數(shù),派生類中也可以不聲明,若基類中未聲明構(gòu)造函數(shù),派生類中也可以不聲明,全采用缺省形式構(gòu)造函數(shù)全采用缺省形式構(gòu)造函數(shù)。 當(dāng)基類聲明有帶形參的構(gòu)造函數(shù)時,派生類也應(yīng)聲當(dāng)基類聲明有帶形參的構(gòu)造函數(shù)時,派生類也應(yīng)聲明帶形參的構(gòu)造函數(shù),并將參數(shù)傳遞給基類構(gòu)造函明帶形參的構(gòu)造函數(shù),并將參數(shù)傳遞給基類構(gòu)造函數(shù)。數(shù)。派生類構(gòu)造函數(shù)的執(zhí)行順序派生類構(gòu)造函數(shù)的執(zhí)行順序1

22、調(diào)用基類構(gòu)造函數(shù),調(diào)用順序按照它調(diào)用基類構(gòu)造函數(shù),調(diào)用順序按照它們們被繼承時聲明的順序被繼承時聲明的順序(從左向右)。(從左向右)。2 調(diào)用成員對象的構(gòu)造函數(shù),調(diào)用順序調(diào)用成員對象的構(gòu)造函數(shù),調(diào)用順序按照它們在類中聲明的順序按照它們在類中聲明的順序。3 派生類的構(gòu)造函數(shù)體中的內(nèi)容。派生類的構(gòu)造函數(shù)體中的內(nèi)容。構(gòu)造函數(shù)的執(zhí)行順序和派生類構(gòu)造函數(shù)中構(gòu)造函數(shù)的執(zhí)行順序和派生類構(gòu)造函數(shù)中列出的名稱順序無關(guān)。列出的名稱順序無關(guān)。/7_5.cpp#include using namespace std;class B1 /基類B1,構(gòu)造函數(shù)有參數(shù)public:B1(int i) coutconstruct

23、ing B1 iendl;class B2 /基類B2,構(gòu)造函數(shù)有參數(shù)public:B2(int j) coutconstructing B2 jendl;class B3 /基類B3,構(gòu)造函數(shù)無參數(shù)public:B3()coutconstructing B3 *endl;class C: public B2, public B1, public B3/派生新類C/注意基類名的順序public:/派生類的公有成員C(int a, int b, int c, int d):B1(a),memberB2(d),memberB1(c),B2(b)/注意基類名的個數(shù)與順序/注意成員對象名的個數(shù)與順序p

24、rivate:/派生類的私有對象成員B1 memberB1;B2 memberB2;B3 memberB3;void main()C obj(1,2,3,4);Constructing B2 2Constructing B1 1Constructing B3 *Constructing B1 3Constructing B2 4Constructing B3 *拷貝構(gòu)造函數(shù)拷貝構(gòu)造函數(shù) 若建立派生類對象時調(diào)用若建立派生類對象時調(diào)用缺省拷貝構(gòu)造缺省拷貝構(gòu)造函數(shù)函數(shù),則編譯器將自動調(diào)用基類的缺省,則編譯器將自動調(diào)用基類的缺省拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)。 若編寫派生類的若編寫派生類的拷貝構(gòu)造函數(shù)拷貝

25、構(gòu)造函數(shù),則需要,則需要為基類相應(yīng)的拷貝構(gòu)造函數(shù)傳遞參數(shù)。為基類相應(yīng)的拷貝構(gòu)造函數(shù)傳遞參數(shù)。例如例如:C:C(C &c1):B(c1)用派生類的引用去初始化基類的引用用派生類的引用去初始化基類的引用析構(gòu)函數(shù)析構(gòu)函數(shù) 析構(gòu)函數(shù)也不被繼承,派生類自行聲明析構(gòu)函數(shù)也不被繼承,派生類自行聲明 聲明方法與一般(無繼承關(guān)系時)類的析構(gòu)函聲明方法與一般(無繼承關(guān)系時)類的析構(gòu)函數(shù)相同。數(shù)相同。 不需要顯式地調(diào)用基類的析構(gòu)函數(shù),系統(tǒng)會自不需要顯式地調(diào)用基類的析構(gòu)函數(shù),系統(tǒng)會自動隱式調(diào)用。動隱式調(diào)用。 析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反。析構(gòu)函數(shù)的調(diào)用次序與構(gòu)造函數(shù)相反。 首先對派生類的新增普通成員進(jìn)行清理。首先

26、對派生類的新增普通成員進(jìn)行清理。 然后對派生類新增的對象成員進(jìn)行清理。然后對派生類新增的對象成員進(jìn)行清理。 最后對所有從基類繼承類的成員進(jìn)行清理。最后對所有從基類繼承類的成員進(jìn)行清理。#include using namecpace std;class B1 /基類基類B1聲明聲明 public:B1(int i) coutconstructing B1 iendl;B1() coutdestructing B1 endl;class B2 /基類基類B2聲明聲明public:B2(int j) coutconstructing B2 jendl;B2() coutdestructing B2

27、 endl;class B3 /基類基類B3聲明聲明public:B3()coutconstructing B3 *endl;B3() coutdestructing B3 endl;class C: public B2, public B1, public B3public:C(int a, int b, int c, int d): B1(a),memberB2(d),memberB1(c),B2(b)private:B1 memberB1;B2 memberB2;B3 memberB3;void main()C obj(1,2,3,4); Constructing B2 2Constru

28、cting B1 1Constructing B3 *Constructing B1 3Constructing B2 4Constructing B3 *Destructing B3Destructing B2Destructing B1Destructing B3Destructing B1Destructing B2二義性問題二義性問題class A public: void f();class B public: void f(); void g();class C: public A, piblic B public: void g(); void h();如果聲明:如果聲明:C c

29、1;則則 c1.f(); 具有二義性具有二義性在多繼承時,基類與派生類之間,在多繼承時,基類與派生類之間,或基類之間出現(xiàn)同名成員時,將或基類之間出現(xiàn)同名成員時,將出現(xiàn)訪問時的二義性出現(xiàn)訪問時的二義性二義性問題二義性問題class B public: int b;class B1 : public B private: int b1;class B2 : public B private: int b2;class C : public B1,public B2 public: int f(); private: int d;bb1bb2dB類成員B類成員B1類成員B2類成員C類對象有二義性:有

30、二義性:C c;c.bc.B:b無二義性:無二義性:c.B1:bc.B2:b當(dāng)派生類從多個基類派生,而這些基類又從當(dāng)派生類從多個基類派生,而這些基類又從同一個基類派生,則在訪問此共同基類中的同一個基類派生,則在訪問此共同基類中的成員時,將產(chǎn)生二義性成員時,將產(chǎn)生二義性五、派生類成員的標(biāo)識與訪問五、派生類成員的標(biāo)識與訪問 二義性問題二義性問題 在多繼承時,基類與派生類之間,或基類之在多繼承時,基類與派生類之間,或基類之間出現(xiàn)同名成員時,將出現(xiàn)訪問時的二義性間出現(xiàn)同名成員時,將出現(xiàn)訪問時的二義性(不確定性)(不確定性) 采用采用虛函數(shù)虛函數(shù)(第(第8章)或章)或同名隱藏規(guī)則同名隱藏規(guī)則來解決。來解

31、決。 當(dāng)派生類從多個基類派生,而這些基類又從當(dāng)派生類從多個基類派生,而這些基類又從同一個基類派生,則在訪問此共同基類中的同一個基類派生,則在訪問此共同基類中的成員時,將產(chǎn)生二義性成員時,將產(chǎn)生二義性采用采用虛基類虛基類來解來解決。決。同名隱藏規(guī)則同名隱藏規(guī)則當(dāng)派生類與基類中有相同成員時:當(dāng)派生類與基類中有相同成員時: 派生類的成員將基類的同名成員隱藏,派生類的成員將基類的同名成員隱藏,派生類對象使用的是派生類中的同名成派生類對象使用的是派生類中的同名成員。員。 如要通過派生類對象訪問基類中被覆蓋如要通過派生類對象訪問基類中被覆蓋的同名成員,應(yīng)使用基類名限定。的同名成員,應(yīng)使用基類名限定。二義性

32、問題二義性問題class A public: void f();class B public: void f(); void g();class C: public A, piblic B public: void g(); void h();如果聲明:如果聲明:C c1;則則 c1.f(); 具有二義性具有二義性解決方法一:用類名和作用域分辨符來限定解決方法一:用類名和作用域分辨符來限定c1.A:f() 或或 c1.B:f()解決方法二:同名覆蓋解決方法二:同名覆蓋在在C 中聲明一個同名成員函數(shù)中聲明一個同名成員函數(shù)f(),f()再根據(jù)再根據(jù)需要調(diào)用需要調(diào)用 A:f() 或或 B:f()#i

33、nclude using namecpace std;class B1 /聲明基類聲明基類B1 public: /外部接口外部接口int nV;void fun() coutMember of B1endl;class B2 /聲明基類聲明基類B2 public: /外部接口外部接口int nV;void fun()coutMember of B2endl;class D1: public B1, public B2 public:int nV;/同名數(shù)據(jù)成員同名數(shù)據(jù)成員void fun()coutMember of D1endl;/同名函數(shù)成員同名函數(shù)成員; void main()D1 d1

34、;d1.nV=1; /對象名對象名.成員名標(biāo)識成員名標(biāo)識, 訪問訪問D1類成員類成員d1.fun(); d1.B1:nV=2;/作用域分辨符標(biāo)識作用域分辨符標(biāo)識, 訪問基類訪問基類B1成員成員d1.B1:fun();d1.B2:nV=3;/作用域分辨符標(biāo)識作用域分辨符標(biāo)識, 訪問基類訪問基類B2成員成員d1.B2:fun();虛基類虛基類 虛基類的引入虛基類的引入 用于有共同基類的場合用于有共同基類的場合 聲明聲明 以以virtual修飾說明基類修飾說明基類例:例:class B1:virtual public B 作用作用 主要用來解決多繼承時可能發(fā)生的對同一基類繼承主要用來解決多繼承時可能

35、發(fā)生的對同一基類繼承多次而產(chǎn)生的二義性問題多次而產(chǎn)生的二義性問題. 為最遠(yuǎn)的派生類提供唯一的基類成員,而不重復(fù)產(chǎn)為最遠(yuǎn)的派生類提供唯一的基類成員,而不重復(fù)產(chǎn)生多次拷貝生多次拷貝 注意:注意: 在在第一級繼承時第一級繼承時就要將共同基類設(shè)計為虛基類就要將共同基類設(shè)計為虛基類虛基類虛基類class B private: int b;class B1 : virtual public B private: int b1;class B2 : virtual public B private: int b2;class C : public B1, public B2 private: float d

36、;下面的訪問是正確的:下面的訪問是正確的:C cobj;cobj.b;虛基類的派生類對象存儲結(jié)構(gòu)示意圖:虛基類的派生類對象存儲結(jié)構(gòu)示意圖:BB1B2Cb1b2dB1類成員B2類成員C類對象bB類成員虛基類舉例虛基類舉例D1nV :int nVd:intB1:nV1:intB2:nV2:intfund():voidfun():voidB1nV1 :intB2nV2 :intD1nVd :intfund():void B0nV :intfun()B0B1新增成員B0B2新增成員D1新增成員B0B0B1B2D1nV,fun()#include using namecpace std;class B0

溫馨提示

  • 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

提交評論