多重繼承的特點、作用/意義和使用條件
多重繼承的特點、意義和使用條件
多重繼承MI:Multiple Inheritance;單一繼承:Single Inheritance;
C++陣營中有兩派:一種是認為多重繼承不好用,一種認為多重繼承好用。實際上,多重繼承有時候效果比單一繼承更好,但是比較複雜;如標準庫的iostream實際就是一個多重繼承得到的類。
多重繼承的特點
在繼承樹只有一層的情況下,多重繼承幾乎等同於按順序單一繼承了若干個類。但是,在繼承樹比較長的情況下,多重繼承的情況會很複雜。
1. 多重繼承的類分為public、private、protected混合的繼承,還包含普通繼承和virtual繼承。
2. 如果一個繼承樹中,從最早的最上面的基類到下面的後面的子類存在兩條或以上的繼承路徑,將會導致子類會有兩條或以上的基類構造路徑,將會導致含有同名稱的重複資料成員。
鑽石型多重繼承:
class BaseBase{};
class BaseA{} : public BaseBase{};
class BaseB{} : public BaseBase{};
class Derive : public BaseA,public BaseB{};
Derive與BaseBase之間有兩條繼承路徑,這將導致Derived會從兩條繼承路徑中分別繼承公共基類中的同名成員。
例:BaseBase::data被BaseA繼承、BaseB繼承,然後Derived繼承BaseA、BaseB,這導致Derive中含有兩個data成員,==**直接使用derive.data呼叫將會導致歧義,必須使用derive.BaseA::data、derive.BaseB::data來呼叫。
如果發生鑽石繼承即含有多個同名稱的成員時,使用virtual避免
繼上:
class BaseA{} : virtual public BaseBase{};
class BaseB{} : virtual public BaseBase{};
class Derive : public BaseA,public BaseB{};
==使用virtual繼承保證多重繼承的時候,被繼承的基類中的成員不會重複==。
virtual繼承的作用和代價
virtual繼承將導致編譯器生成的程式碼更大,生成的程式速度減慢。
作用:當某個類可能作為其他類的基類的時候,且它繼承自某個類,則使用virtual繼承,可以讓它繼承的類中如果有與其它共同基類重名的情況,不會導致保留兩份成員而只會保留一份。
virtual base class的使用
如果有必要使用多重繼承時,平常最好使用普通的繼承即non-virtual繼承;必須使用virtual繼承時,儘可能避免在virtual base class中定義資料成員,防止多條路徑繼承時產生多個同名稱的資料成員。
C++中不帶資料成員的virtual base class類似於Java和C#的介面類interface;Java、C#不允許在介面類中定義資料成員的原因與C++的相同,都是防止同名數據成員有多個副本
總結:多重繼承在不得已的情況下可以使用,但是幾乎可以肯定存在不需要多重繼承就能解決問題的方案;如果使用多重繼承,應該考慮是否要使用virtual繼承;如果使用virtual繼承,則virtual base class最好不要定義任何資料成員,這樣生成的程式碼速度更快、更小且降低複雜度
本人公眾號:taojuxiu