多重繼承是
c++語言獨有的繼承方式,其它幾乎所有語言都秉承了單一繼承的思想。這是因為多重繼承致命的缺陷導致的。
當繼承基類時,在派生類中就獲得了基類所有的資料成員副本。假如類b從
a1和a2兩個類多重繼承而來,這樣
b類就包含a1、
a2類的資料成員副本。
考慮如果a1、
a2都從某基類派生,該基類稱為
base
,現在繼承關係如下:
菱形繼承關係
我們c++
語言來描述這種繼承關係:
class base;
class a1 :public base ;
class a2 :public base ;
class b :public a1,public a2 ;
那麼a1、a2
都具有base
的副本。這樣
b就包含了
base
的兩個副本,副本發生了重疊,不但增加了儲存空間,同時也引入了二義性。這就是菱形缺陷,菱形缺陷實際是兩個缺陷:
子物件重疊;
向上對映的二義性。
菱形缺陷的其中一種解決辦法
在c++
世界裡最廣泛的使用虛擬繼承解決菱形缺陷的應用便是標準
c++的輸入/輸出
標準c++的輸入/輸出
對繼承而來的虛函式改寫很容易,但是如果是在改寫乙個「在兩個基類都有相同原型」的虛函式情況就不那麼容易了。
提出問題:
假設汽車最大速度的介面為
icar
,潛艇最大速度的介面為
iboat
,有乙個兩棲類的交通工具它可以奔跑在馬路上,也可以航行在大海中,那麼它就同時擁有
icar
、iboat
兩種交通工具的最大速度特性,我們定義它的介面為
icarboat;
class icar ;
class iboat ;
我們先對
icarboat
的介面做乙個嘗試:
class ccarboat ;
解決問題:
顯然上面這個嘗試根本就無法成功,只用乙個實現方法,怎麼能夠求出這個
icarboat
交通工具奔跑在馬路上的最高時速,同時也能夠求出航行在大海上的最大航行速度呢。
上面這一問題矛盾就在於乙個方法,卻需要兩個答案。看來
icarboat
要返回兩個答案就必須有兩個方法了,我們假設乙個方法是求在陸地上奔跑的速度,名稱為
getcarmaxspeed
();另乙個方法是求在大海上航行的最大速度,名稱為
getboatmaxspeed
();那這兩個方法又怎麼和
getmaxspeed
()介面方法聯絡起來呢;幸運的是,我們找到了解決辦法,而且解決辦法有很多種,下面介紹一下繼承法。
多重介面與方法名衝突問題
多重繼承(菱形繼承)
多重繼承 經典的是菱形繼承,如圖。菱形繼承將會產生的問題 把基類a中的成員變數通過b和c兩次繼承至d。d的繼承結構 可以看到,ma被繼承兩次至d 那麼將如何解決這個問題呢?採用虛繼承的方法,將基類a中的ma直接繼承至d。如下 class a int ma class b virtual public...
c 多重繼承 虛繼承 菱形繼承
多重繼承的特性和使用和單繼承沒區別。按照單繼承來使用即可。多重繼承可能會引入乙個 菱形繼承的問題 這個問題其實並不算問題,因為它合情合理,即多個基類 擁有乙個共同的基類,那麼在構造的時候,由於構造的遞迴特性,就會出現共同基類出現兩份例項的 情況,而且如果針對性修改,那麼如果不在訪問共同基類的時候先指...
多重繼承有什麼缺陷。
在 設計模式 一書中,作者在開篇中就提出了物件導向的兩條基本設計原則 1 多對介面程式設計,少對實現程式設計。2 多使用聚合,少使用繼承。繼承的過多使用當然會帶來高耦合,當然聚合的過分會使模組過多。多重繼承指的是乙個類別可以同時從多於乙個父類繼承行為與特徵的功能,是一種圖狀層次結構 有向無環圖 功能...