C 之多重繼承

2022-09-14 06:57:07 字數 2670 閱讀 3703

c++中,所謂的多繼承是指乙個派生類可以有多個基類,這樣就可能帶來以下幾方面的問題:

(1)多個基類中存在相同名稱時

如果乙個派生類繼承的多個基類中包含有相同名稱的函式時,有可能會產生呼叫不明確,即發生歧義,比如如下**:

1

class

borrowableitem2;

67class

electronicgadget8;

1213

class ***player : public borrowableitem, public

electronicgadget;

1415

***player ***;

16 ***.checkout();

view code

上述**中物件***呼叫函式checkout時就會產生歧義,因為它的基類中都含有函式checkout。編譯器在查詢可用的函式時,首先查詢最佳匹配函式,然後再檢查其是否可用,上面的兩個基類的函式具有相同的匹配度,沒有所謂的最佳匹配,因而編譯器也不會檢查可取用性。

為了指明到底是呼叫哪個基類的函式,通常需要如下指定:

***.borrowableitem.checkout();
(2)鑽石繼承體系

如果乙個派生類繼承的多個基類中,向上還要繼承其他的類,例如

class

file ;

class inputfile : public

file ;

class outputfile : public

file ;

class iofile : public inputfile, public outputfile ;

這種形式的繼承像極了鑽石,因而也稱鑽石繼承:

這種繼承帶來了這樣的問題:如果乙個繼承體系中從乙個base class到乙個derived class有乙個以上的通路,那麼該讓base class的成員變數在每乙個通路中的derived class中都複製一次嗎?如果是,那麼這種複製必然會帶來不必要的空間開銷, 例如在上面的繼承體系中,如果file中包含有乙個filename變數,那麼iofile類中就會包含兩份filename變數的空間,這在現實中顯然是不合理的。

對此,c++提供兩種方案:第一種預設做法是提供複製,即上面的做法;第二是對基類進行virtual繼承,形式如下:

1

class

file ;

2class inputfile : virtual

public

file ;

3class outputfile : virtual

public

file ;

4class iofile : public inputfile, public outputfile ;

view code

這種改變理論上來講總是合理的,即public繼承應當為virtual public繼承,但是之所以不這麼做的原因是,為了處理成員變數重複的問題,編譯器需要做很多複雜的事情,對應的產生的派生類物件的體積也更大,訪問virtual base class成員變數的速度也更慢。

此外,對virtual base class的初始化也更加複雜,其初始化責任由最底層的派生類承擔(一般的繼承中不是如此嗎?)。

基於以上,可以看到,如果必須使用virtual base class,那麼最好在virtual base class中少放資料,以避免初始化時可能帶來的詭異行為。

(3)多重繼承的合理性

如果乙個類的許多實現可以通過使用已有的類的實現達到便利,即"is-implemented-in-terms-of",那麼可能需要private繼承,當然這裡也可以使用復合加public繼承,假如這裡執意用private繼承。另一方面,該類還需要實現某個介面類,即必須通過public繼承某個包含許多介面的類,那麼多重繼承看來就是合理的:

1

class

iperson2;

89class

databaseid ;

10class

personinfo11;

2122

class cperson : public iperson, private

personinfo

2326

virtual

string name() const

2730

virtual

string birthdate() const

3134

35private:36

const

char* valuedelimopen() const

37 cpnst char* valuedelimclose() const

38 };

view code

總結來講,多重繼承會產生歧義性,可能需要引入virtual base class,而virtual base class又可能造成大小、速度、初始化複雜度增加的成本,因而如果能避免使用多重繼承,就應該避免。在某寫場合下,比如需要public繼承乙個藉口類和private繼承乙個協助實現的類時,採用多重繼承會帶來便利。

以上整理自effective c++中文版第三版case 40.

C 之多重繼承

當子類繼承於多個父類時,有以下兩種情況存在,稱之為多重繼承 多重繼承 include stdafx.h include includeusing namespace std 父類中同名函式如何區分 class a void print class b 父類b void print class c p...

C 之多重繼承

大多數應用程式使用單個基類的公用繼承,但是在某些情況下,單繼承是不夠的,必須使用多繼承。c 允許為乙個派生類指定多個基類,這樣的繼承結構被稱做多重繼承.舉個例子,交通工具類可以派生出汽車和船連個子類,但擁有汽車和船共同特性水陸兩用汽車就必須繼承來自汽車類與船類的共同屬性。如下圖示 實現 多重繼承 i...

python之多重繼承

因為繼承可以獲取父類的屬性以及函式,所以繼承在物件導向程式設計中是乙個重要的方式,但是,如果物件中的繼承關係過多,就會導致繼承層次太多,因此出現了多重繼承的概念,即繼承不再是一對一,而是可以乙個子類繼承多個父類的方式,方法就是在類後面的括號用逗號隔開每乙個繼承類 如下 class animal ob...