C 知識點53 虛繼承

2021-10-10 20:44:02 字數 1868 閱讀 6008

二、虛繼承

1.概念

預設情況下,c++的派生列表中不允許同乙個基類出現兩次,但是,如果兩個基類都繼承了同乙個類a,那麼兩個基類派生出的子類就會包含兩次類a的部分

為了解決上述問題,c++中就出現了虛繼承,通過虛繼承,無論虛基類在整個繼承鏈**現了多少次,子類中都只出現一次。

示例

class animal

通過輸出結果顯示,animal只建立了一次,如果將派生列表的virtual關鍵字去掉,輸出結果如下

所以,上述**通過虛繼承,讓基類animal只在子類**現了一次

2.規則

和單一繼承與多重繼承一樣,虛繼承的的子類物件可以切割轉化成對應的基類,可以通過基類的指標或者引用指向子類物件

成員的查詢規則和單一繼承以及多重繼承一樣

見部落格

3.虛繼承的問題

與非虛多重繼承一樣,如果在多個不同的基類中定義了同名的成員,會出現二義性問題,解決辦法依然是指定作用於或者在子類中也定義同名的成員,見部落格

4.建構函式與虛繼承

在單一繼承和非虛多重繼承的情況下,建立乙個子類物件時,各個類的構造的順序是按照派生列表中類出現的順序來呼叫的。

但是虛繼承不一樣,在虛繼承的體系中,建立乙個子類物件時,虛基類總是先於非虛基類構造。

示例class a

過程如下:首先檢視派生列表。發現有虛基類,第乙個發現的虛基類時a,所以先建立a部分,呼叫a的建構函式,然後發現了虛基類d,於是就建立d並呼叫d的建構函式,虛基類都建立完成了,開始建立非虛基類,非虛基類在派生列表中的出現順序分別是c,b,所以建立並呼叫了c和b的建構函式,最後建立e並呼叫e的建構函式

析構順序和構造的順序正好相反

如果乙個虛基類既是基類也是子類,在建立虛基類的時候,依然會建立虛基類的基類

示例

class a
{public:

上述**中,先出現了一條警告,這是因為a在f的物件中存在兩份,當訪問a中的元素時,無法確定到時是訪問哪個a中的元素,編譯器分不出來,但是只要不訪問a中的元素編譯器就不會報錯

因為在f的派生類列表中先發現的是虛基類b,而虛基類b又是a的子類,所以先建立a,然後建立b,之後按照非虛基類在派生列表**現的順序分別建立cde,接著在派生列表中又發現了乙個a,於是又建立了乙個a,最後建立f,析構函式的呼叫順序仍然和建構函式相反

所以,當乙個基類在子類物件中建立兩份時,訪問出現兩份的基類成員時會出現二義性問題,因為編譯器無法區分到底要訪問哪個基類中的對應的成員

比如在a中新增乙個成員at,訪問時,就會出現如下錯誤

提示有二義性

多重繼承也有這個問題

所以在實際應用中,虛繼承和多重繼承用的很少,單一繼承用的較多

參考《c++ primer》

C 知識點隨筆 五 虛繼承

虛繼承的出現就是為了解決多繼承中訪問不明確的問題。首先讓我們先看一下虛繼承的 include using namespace std class aa class bb virtual public aa class cc virtual public aa class dd public bb,p...

面試知識點總結 虛繼承

背景 儘管在派生列表中同乙個基類只能出現一次,但實際上派生類可以多次繼承同乙個類。派生類可以通過它的兩個直接基類分別繼承同乙個間接基類,也可以直接繼承某個基類,然後通過另乙個基類再一次間接繼承該類。出現的問題 在預設情況下,派生類中含有繼承鏈上每個類對應的子部分。如果某個類在派生過程中出現了多次,則...

C 繼承相關知識點

c 作為物件導向的語言,類之間可以繼承,被繼承的類稱為基類 父類 產生的新類稱為派生類 子類 c 的類許可權分為三個等級,private 私有的 protect 被保護的 public 公有的 其相對應的繼承的許可權也分為相同的三個等級,即private,protect以及public繼承。這三類繼...