C程序設計課件:第17章 多重繼承_第1頁
C程序設計課件:第17章 多重繼承_第2頁
C程序設計課件:第17章 多重繼承_第3頁
C程序設計課件:第17章 多重繼承_第4頁
C程序設計課件:第17章 多重繼承_第5頁
已閱讀5頁,還剩35頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、第17章 多重繼承本章主要內(nèi)容 17.1 多繼承如何工作 17.2 繼承的模糊性 17.3 虛擬繼承 17.4 多繼承的構(gòu)造順序 17.5 繼承的訪問控制 17.6 保護繼承與私有繼承 作業(yè)217.1多繼承如何工作 多重繼承即多繼承:由多個基類派生而成新的類 例如,兩用沙發(fā),它是一個沙發(fā),也是一張床,兩用沙發(fā)應允許同時繼承沙發(fā)和床的特性,即SleeperSofa類繼承Bed和Sofa兩個類。3Sleep()SetWeight()BedWeightWatchTv()SetWeight()SofaWeightFoldOut()SleeperSofa床和沙發(fā)的分解4/* ch17_1.cpp *#i

2、ncludeclass Bed public: Bed() :weight(0) void Sleep() coutSleeping.n; void SetWeight(int i) weight =i; protected: int weight;class Sofa public: Sofa() :weight(0) void WatchTV() cout Watching TV.n; void SetWeight(int i) weight =i; protected: int weight;5class SleeperSofa :public Bed, public Sofa publ

3、ic: SleeperSofa() void FoldOut() /折疊與打開 coutFold out the sofa.n; ;int main() SleeperSofa ss; ss.WatchTV(); ss.FoldOut(); ss.Sleep();運行結(jié)果:Watching TV.Fold out the sofa.Sleeping617.2 繼承的模糊性 模糊性:二義性二義性:對某個成員訪問不能唯一確定二義性產(chǎn)生的原因:不同類的成員可以同名規(guī)定:在多繼承、多層次的繼承結(jié)構(gòu)中,總是逐層往上、訪問最靠近自己的那個同名成員。但是,如果在同一層的兩個類中具有同名成員,則產(chǎn)生二義性。

4、7int main() sleepersofa ss; ss.SetWeight(20); /error /是Bed的SetWeight還是sofa的SetWeight?這導致了名稱沖突,在編譯時將予以拒絕。程序必須在重量面前說明基類int main() sleepersofa ss; ss.Sofa:SetWeight(20); /說明是沙發(fā)重量20斤17.2 繼承的模糊性817.2 繼承的模糊性 二義性解決辦法: 在成員名前用類名進行限定(類名:成員名),可以解決同一層的兩個類中具有同名成員而產(chǎn)生的二義性。 虛基類(即虛擬繼承),可以解決上述訪問同一個基類的成員,但存在多條路徑的問題。91

5、7.3 虛擬繼承 從意義上來看,一個SleepSofa沒有沙發(fā)和床兩種重量,如此的繼承不是真實的現(xiàn)實世界描述。進一步分析可得,床和沙發(fā)都是家具的一種,凡家具都有重量,所以通過分解來考察其關(guān)系。10GetWeight()SetWeight()FurnitureWeightGetWeight()SetWeight()FurnitureWeightSleep()BedWatchTv()SofaFoldOut()SleeperSofa沙發(fā)床的分解11/* ch17_2.cpp *#includeclass Furniture public: Furniture() void SetWeight(int

6、 i) weight =i; int GetWeight() return weight; protected: int weight;class Bed :public Furniture public: Bed() void Sleep() cout Sleeping.n; ;12class Sofa :public Furniture public: Sofa() void WatchTV() cout Watching TV.n; ;class SleeperSofa :public Bed, public Sofa public: SleeperSofa() :Sofa(), Bed

7、() void FoldOut() cout Fold out the sofa.n; ;int main() SleeperSofa ss; ss.SetWeight(20); /編譯出錯!模糊的SetWeight成員 Furniture* pF; pF=(Furniture*)&ss; /編譯出錯!模糊的Furniture* cout GetWeight() endl;13GetWeight()SetWeight()FurnitureWeightGetWeight()SetWeight()FurnitureWeightSleep()BedWatchTv()SofaFoldOut()Slee

8、perSofaSleeperSofa的實際繼承關(guān)系14Furniture weightBed繼承部分 Furniture weightSofa繼承部分SleepSofa繼承部分床部分沙發(fā)部分SleepSofa完整對象完整的SleeperSofa對象內(nèi)存布局1517.3 虛擬繼承 虛擬繼承的概念: 在多條繼承路徑上存在一個公共的基類,在這些路徑的匯合處(某個派生類)就產(chǎn)生這個公共基類的多個“副本”。如果只希望存在一個副本,可以把此公共基類聲明為虛基類(虛擬繼承)。 虛擬繼承的方法: 虛基類是對派生類而言,所以,虛基類本身的定義不變,在定義派生類時聲明該基類為虛基類即可(冠以關(guān)鍵字:virtual

9、)。 16/* ch17_3.cpp *#includeclass Furniture public: Furniture() void SetWeight(int i) weight =i; int GetWeight() return weight; protected: int weight;class Bed :virtual public Furniture public: Bed() void Sleep() cout Sleeping.n; ;17class Sofa :virtual public Furniture public: Sofa() void WatchTV()

10、cout Watching TV.n; ;class SleeperSofa :public Bed, public Sofa public: SleeperSofa() :Sofa(), Bed() void FoldOut() cout Fold out the sofa.n; ;int main() SleeperSofa ss; ss.SetWeight(20); cout ss.GetWeight() endl;運行結(jié)果: 20 18 Furniture weightBed繼承部分Sofa繼承部分SleeperSofa部分虛擬繼承的完整SleeperSofa對象虛擬繼承的Sleepe

11、rSofa內(nèi)存布局虛擬繼承的虛擬和虛擬函數(shù)的虛擬沒有任何關(guān)系!1917.4 多繼承的構(gòu)造順序派生類的構(gòu)造函數(shù)調(diào)用次序(調(diào)用原則):1. 先基類,再成員,后自己。2. 在同一層上如有多個基類,則先虛基類,后非虛基類。3. 在同一層上如有多個虛基類,則按派生時定義的先后次序執(zhí)行;在同一層上如有多個非虛基類,則按派生時定義的先后次序執(zhí)行。 4. 對于一個派生類的某個虛基類的構(gòu)造函數(shù)一旦被執(zhí)行過,就不再被多次執(zhí)行。5. 虛基類的派生類的構(gòu)造函數(shù)的定義無特殊規(guī)定。2017.4 多繼承的構(gòu)造順序6. 如果“最后派生類”的構(gòu)造函數(shù)的初始化列表中不調(diào)用虛基類的構(gòu)造函數(shù),則該派生類的虛基類的構(gòu)造函數(shù)必須是無參的

12、,或全部是缺省值的構(gòu)造函數(shù)7. 如果“最后派生類”的構(gòu)造函數(shù)的初始化列表中不調(diào)用虛基類的構(gòu)造函數(shù),則虛基類的初始值采用其構(gòu)造函數(shù)的缺省值;如果“最后派生類”的構(gòu)造函數(shù)的初始化列表中調(diào)用了虛基類的構(gòu)造函數(shù),并且?guī)氤跏贾?,則虛基類的初始值采用帶入的值。21/* ch17_4.cpp *#includeclass OBJ1 public: OBJ1() cout OBJ1n; ;class OBJ2 public: OBJ2() cout OBJ2n; ;class Base1 public: Base1() cout Base1n; ;class Base2 public: Base2() co

13、ut Base2n; ;22class Base3 public: Base3() cout Base3n; ;class Base4 public: Base4() cout Base4n; ;class Derived :public Base1, virtual public Base2, public Base3, virtual public Base4 protected: OBJ1 obj1; OBJ2 obj2; public: Derived() :Base4(), Base3(), Base2(), Base1(), obj2(), obj1() cout Derived

14、ok.n; ;23int main() Derived aa; cout This is ok.n;運行結(jié)果: Base2 Base4 Base1 Base3 OBJ1 OBJ2 Derived ok. This is ok. 在語言中實現(xiàn)多重繼承并不容易,這主要是編譯程序問題,還有模糊性問題。建議你如果可能,盡量避免用多重繼承。單個繼承提供了足夠的功能,不一定非用多重繼承不可。24#includeclass Base1 /虛基類 private: int a,b; public: Base1(int aa=0,int bb=0) /構(gòu)造函數(shù):是帶缺省值的,或者是無參數(shù)的 a=aa; b=bb

15、; coutBase1 class!endl; void show()coutBase1: a=a b=bendl; ;class Base2 public: Base2() coutBase2 class!endl; void show2() coutBase2: endl; ;25class Level1: public Base2,virtual public Base1 public: Level1(int a,int b):Base1(a,b) coutLevel1 class!endl; ;class Level2:public Base2,virtual public Base1

16、 /虛基類 public: Level2(int a,int b):Base1(a,b) coutLevel2 class!endl; ;class Lastlevel: public Level1,virtual public Level2 public: Lastlevel(int a,int b):Level1(a,b), Level2(a,b) /Lastlevel(int a,int b):Level1(a,b), Level2(a,b), Base1(a,b) coutLastlevel class!endl; ;26int main() Lastlevel obj(7,9); o

17、bj.show(); /直接調(diào)用間接基類base的公有成員函數(shù)show(),無二義性 /obj.show2(); error /訪問間接基類base2的公有成員函數(shù)show2(),存在二義性 執(zhí)行結(jié)果:Base1 class!Base2 class!Level2 class!Base2 class!Level1 class!Lastlevel class!Base1: a=0 b=0 /Base1: a=7 b=9 2717.5 繼承類別及其訪問控制繼承方式基類成員特性基類中的成員在派生類中的特性公有繼承(public)publicpublicprotectedprotectedprivate

18、不可訪問私有繼承(private)publicprivateprotectedprivateprivate不可訪問保護繼承(protected)publicprotectedprotectedprotectedprivate不可訪問2817.5 繼承類別及其訪問控制公有成員:一個類的公有成員允許本類的成員函數(shù)、本類的對象、公有派生類的成員函數(shù)、公有派生類的對象訪問。私有成員:一個類的私有成員只允許本類的成員函數(shù)訪問。保護成員:具有私有成員和公有成員的特性,對其派生類而言是公有成員,對其對象而言是私有成員。2917.5 繼承類別及其訪問控制公有繼承:基類的公有段成員被繼承為公有的,基類的保護段成

19、員被繼承為保護的。派生時用“public”作訪問控制。私有繼承:基類的公有段成員被繼承為私有的,基類的保護段成員被繼承為私有的,派生時用“private”作訪問控制。保護繼承:基類的公有段成員被繼承為保護的,基類的保護段成員被繼承為保護的,派生時用“protected”作訪問控制。30class Base public: int m1; protected: int m2; private: int m3;class PrivateClass:private Base /私有繼承 public: void test() m1=1; /ok:將m1據(jù)為private m2=2; / ok:將m2

20、據(jù)為private m3=3; /不可訪問 ;31class DerivedFromPri:public PrivateClass public: void test() m1=1; /不可訪問基類的私有成員 m2=2; /不可訪問 m3=3; /不可訪問 ;class ProtectedClass:protected Base /保護繼承 public: void test() m1=1; /m1據(jù)為protected m2=2; /m2據(jù)為protected m3=3; /不可訪問 ;32class DerivedFromPro:public ProtectedClass public:

21、void test() m1=1; /m1為protected m2=2; /m2仍為protected m3=3; /不可訪問 ;class PublicClass:public Base /公共繼承 public: void test() m1=1; /m1為public m2=2; /m2為protected m3=3; /不可訪問 ; 33class DerivedFromPub:public PublicClass public: void test() m1=1; /m1仍保持為public m2=2; /m2仍保持為protected m3=3; /不可訪問 ;int main(

22、) PrivatedClass priObj1; priObj1.m1=1; /error priObj1.m2=2; /error priObj1.m3=3; /error ProtectedClass proObj2; priObj2.m1=1; /error priObj2.m2=2; /error priObj2.m3=3; /error PublicClass pubObj3; priObj3.m1=1; /ok priObj3.m2=2; /error priObj3.m3=3 /error3417.5 繼承類別及其訪問控制 私有繼承時,基類中不管是公有還是保護的成員,在子類中一律

23、變成私有成員。保護繼承時,基類中公共和保護的成員在子類中變成保護的。公共繼承時,基類中為公共、保護的成員在子類中仍保持為公共、保護的。在繼承關(guān)系中,基類的private成員不但對應用程序隱藏,對派生類也隱藏。而基類的保護成員則只對應用程序隱藏,而對派生類則毫不隱瞞。 3517.6 保護繼承與私有繼承一個私有的或保護的派生類不是子類,因為非公有的派生類不能做基類能做的所有的事情,但有與基類相似的行為。例如,下面的代碼定義了一個私有繼承基類的類。 #include class Animal public: Animal() void eat() couteatn ; ;36class Giraffe:private Animal public: Giraffe() void StrechNeck(double) coutstrechn;class Cat:public Animal public: Cat() void Meaw(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論