C++菱形繼承

清風颺發表於2016-05-20

菱形繼承是多重繼承中跑不掉的,Java拿掉了多重繼承,輔之於介面。C++中雖然沒有明確說明介面這種東西,但是隻有純虛擬函式的類可以看作Java中的介面。在多重繼承中建議使用“介面”,來避免多重繼承中可能出現的各種問題。

說到菱形繼承,就要說到虛繼承的概念,對於虛繼承,就是為了解決從不同途徑繼承來的同名的資料成員在記憶體中有不同的拷貝造成資料不一致問題,將共同基類設定為虛基類。這時從不同的路徑繼承過來的同名資料成員在記憶體中就只有一個拷貝,同一個函式名也只有一個對映。這樣不僅就解決了二義性問題,也節省了記憶體,避免了資料不一致的問題。
class 派生類名:virtual 繼承方式 基類名
virtual是關鍵字,宣告該基類為派生類的虛基類。
在多繼承情況下,虛基類關鍵字的作用範圍和繼承方式關鍵字相同,只對緊跟其後的基類起作用。
宣告瞭虛基類之後,虛基類在進一步派生過程中始終和派生類一起,維護同一個基類子物件的拷貝。

1.菱形繼承

先看一下菱形繼承長什麼樣。
這裡寫圖片描述

B和C從A中繼承,而D多重繼承於B,C。那就意味著D中會有A中的兩個拷貝。因為成員函式不體現在類的記憶體大小上,所以實際上可以看到的情況是D的記憶體分佈中含有2組A的成員變數。如下程式碼:

轉化為程式碼形式 

class A{}; //基類

class B:public A{};//子類

class C:public A{};

class D:public B,public C();

如上程式碼中A,B,C,D就構成了一個菱形繼承,如果不用虛基類來實現菱形繼承就會導致模糊呼叫的現象,所謂模糊呼叫就是說在D的記憶體中會保留兩個基類A的物件,如何解決這個問題,利用虛基類就能很好的解決這個問題,即可改為

class B:virtual public A{};//子類



class C:virtual public A{};

這就是c++臭名昭著的菱形繼承現象,而java則沒有

相關文章