C 多重繼承與虛擬繼承

2022-03-27 01:33:54 字數 3195 閱讀 4634

本文只是粗淺討論一下c++中的多重繼承和虛擬繼承。

我們先來看一下簡單的例子:

1 #include 2

using

namespace

std;34

classa5

14 ~a()

15};

1617

class b : publica18

27 ~b()

28};

2930

class c : publica31

40 ~c()

41};

4243

class d : public b, publicc44

53 ~d()

54};

5556

intmain()

57

上述程式的輸出為:

由上邊結果可以看出,析構函式呼叫次序跟建構函式是相反的。另外,構造函式呼叫次序跟類d繼承b、c次序(public b, public c)相關。

可能我們也發現了,對於類d的例項d來說,它其實有兩個重複的a例項。我們應該要去掉其中乙個以節省空間。具體做法就是採用虛擬繼承的方法:

1

class b : public

virtuala2

;56class c : public

virtuala7

;

這是程式的輸出就會變成:

可見這個時候類d的例項d就只有乙個類a例項。

請看下邊程式:

1 #include 2

using

namespace

std;34

classa5

14 ~a()

15char getid()

16};

1718

class b : public

virtuala19

28 ~b()

29char getid()

30};

3132

class c : public

virtuala33

42 ~c()

43char getid()

44};

4546

class d : public b, publicc47

56 ~d()

57//

char getid()

58};

5960

intmain()

61

在main函式中,第63行的d.getid()會優先在類d中查詢有沒有getid()的定義,如果沒有就會到其父類查詢;而恰好其父類b、c(同級)均定義了相同的getid()(類a的getid()定義存不存在都沒關係),這時d.getid()就不知道要呼叫b類中的getid()還是c類中的,從而導致二義性。

不過我們可以通過d.b::getid()、d.c::getid()來指明具體要呼叫哪乙個類的getid。但我們總不會想到這樣子去做,而且這樣子做也比較麻煩。

對於多重繼承的虛函式同樣存在二義性。

先看一下程式:

1 #include 2

using

namespace

std;34

classa5

14 ~a()

15char getid()

16};

1718

class b : public

virtuala19

28 ~b()

29char getid()

30};

3132

class c : public

virtuala33

42 ~c()

43char getid()

44};

4546

class d : public b, publicc47

56 ~d()

57char getid()

58};

5960

intmain()

61

程式輸出如下:

上邊程式第63~65行相當於a、b、c將d進行了分割(函式是否是虛函式在這裡並無關係,而且注意這裡的a、b、c、d都不是指標),分割出屬於自己的部分,所以呼叫getid()的時候能正確反映具體的類。

我們再來看乙個程式:

1 #include 2

using

namespace

std;34

classa5

14 ~a()

15virtual

char getid()

16};

1718

class b : public

virtuala19

28 ~b()

29virtual

char getid()

30};

3132

class c : public

virtuala33

42 ~c()

43virtual

char getid()

44};

4546

class d : public b, publicc47

56 ~d()

57virtual

char getid()

58};

5960

intmain()

61

程式的輸出如下:

從輸出結果可以看出,類d的getid覆蓋其所有父類的getid。需要注意的是,當我們在類d的乙個父類,如a中不設定getid為虛函式,則「a *a = d」的效果仍然跟分割d指向的記憶體的效果一樣。

C 類的多重繼承與虛擬繼承

摘自 http tech.ddvip.com 2006 12 116512057312798.html 在過去的學習中,我們始終接觸的單個類的繼承,但是在現實生活中,一些新事物往往會擁有兩個或者兩個以上事物的屬性,為了解決這個問題,c 引入了多重繼承的概念,c 允許為乙個派生類指定多個基類,這樣的繼...

C 類的多重繼承與虛擬繼承

在過去的學習中,始終接觸的單個類的繼承,但是在現實生活中,一些新事物往往會擁有兩個或者兩個以上事物的屬性,為了解決這個問題,c 引入了多重繼承的概念,c 允許為乙個派生類指定多個基類,這樣的繼承結構被稱做多重繼承。舉個例子,交通工具類可以派生出汽車和船連個子類,但擁有汽車和船共同特性水陸兩用汽車就必...

C 多重繼承與虛繼承

在派生類中對基類成員的訪問應該是唯一的。但是,在多繼承情況下,可能造成對基類中某個成員的訪問出現了不一致的情況,這時就稱對基類成員的訪問產生了二義性。派生類在訪問基類成員函式時,由於基類存在同名的成員函式,導致無法確定訪問的是哪個基類的成員函式,因此出現了二義性錯誤。例如 includeusing ...