天天看點

C++多重繼承與虛基類及與.NET的比較

多重繼承

前面我們介紹的派生類隻有一個基類,稱為單基派生或單一繼承。在實際運用中,我們經常需要派生類同時具有多個基類,這種方法稱為多基派生或多重繼承。

2.1 多重繼承的聲明:

在 C++ 中,聲明具有兩個以上基類的派生類與聲明單基派生類的形式類似,隻需将要繼承的多個基類用逗号分開即可。

在多重繼承中,公有派生和私有派生對于基類成員在派生類的可通路性與單繼承的規則相同。

另外,對基類成員的通路必須是無二義的,若兩個基類中具有同名的資料成員或成員函數,使用成員名限定來消除二義性,若派生類中新增成員或成員函數與基類成員或成員函數同名,則派生類會覆寫外層同名成員,也須使用作用域分辨符。

2.2 多重繼承的構造函數和析構函數:

多重繼承的構造函數的定義形式與單繼承構造函數的定義形式類似,隻有 n 個基類的構造函數之間用“,”分隔。

多重繼承的構造函數的執行順序與單繼承構造函數的執行順序相同,也是遵循先執行基類的構造函數,再執行對象成員的構造函數,最後執行派生類構造函數的原則。在多個基類之間,則嚴格按照派生類聲明是從左到右的順序來排列先後。而析構函數的執行順序與構造函數的執行順序相反。

2.3 虛基類 :

如果某個派生類的部分或全部直接基類是從另一個共同的基類派生而來,在這些基類中,從上一級基類繼承來的成員就有相同的名稱,則在這個派生類中通路這個共同的基類中的成員時,可能會産生二義性,此時,可定義虛基類。這就要求在其直接基類的定義中,使用關鍵字 virtual 将那個共同的基類定義為虛基類,其文法形式如下:

class 派生類名: virtual 派生方式 基類

虛基類的初始化與一般的多重繼承的初始化在文法上是一樣的 ,但構造函數的調用順序不同,虛基類構造函數的調用順序是這樣規定的:

1) 在同一層次中,先調用虛基類的構造函數,接下來依次是非虛基類的構造函數,對象成員的構造函數,派生類的構造函數。

2) 若同一層次中包含多個虛基類,這些虛基類的構造函數按對他們說明的先後次序調用

3) 若虛基類由非虛基類派生而來,則仍然先調用基類構造函數,再調用派生類構造函數。

上面是理論,有點兒晦澀,下面舉一個例子.以下圖為例:

C++多重繼承與虛基類及與.NET的比較

接口Common是所有類的公共接口,Server接口繼承Common接口,Client接口繼承Common接口,CommonImpl是Common接口的一個公共實作。ServerImpl是Server接口的實作,它的Common接口的實作直接使用CommonImpl類的實作。

如果在C#中,這個問題會自然而優雅的解決,即編譯器會知道,如果1個類繼承了Server接口,又繼承了CommonImpl實作,那麼ServerImpl隻需要實作Server接口中特定的方法即可。唯一的限制是CommonImpl必須放在Server接口的前面。看下面的示範代碼:

類CB隻需要實作接口IB中的方法即可。CA,IB必須以這個順序出現;

對于C++而言,編譯器是不知道的,如果你希望所有子類共享一個基類,或者子類都共用一個通用實作的基類,那麼你需要把共享的那部分,聲明為virutal基類,上圖中的例子,就必須把Common的子類繼承,聲明為虛基類繼承。

上面的代碼編譯可以通過,且結果如期望。如果去掉virtual繼承修飾符,就會報錯。

本文轉自斯克迪亞部落格園部落格,原文連結:http://www.cnblogs.com/sgsoft/archive/2010/07/20/1781724.html,如需轉載請自行聯系原作者

上一篇: MapReduce簡介

繼續閱讀