背景:
儘管在派生列表中同乙個基類只能出現一次,但實際上派生類可以多次繼承同乙個類。派生類可以通過它的兩個直接基類分別繼承同乙個間接基類,也可以直接繼承某個基類,然後通過另乙個基類再一次間接繼承該類。
出現的問題:
在預設情況下,派生類中含有繼承鏈上每個類對應的子部分。如果某個類在派生過程中出現了多次,則派生類中將包含該類的多個子物件,這對於一些類時行不通的。比如iostream繼承了istream和ostream,而istream和ostream都繼承自base_ios,因此iostream繼承了base_ios兩次。但是乙個iostream物件肯定希望在同乙個緩衝區中進行讀寫操作,也會要求條件狀態能同時反映輸入和輸出操作的情況。假如在iostream中包含了base_ios的兩份拷貝,則上述的共享行為就無法實現。
解決方法:
通過虛繼承的機制解決上述問題。虛繼承的目的是令某個類做出宣告,承諾願意共享它的基類。其中,共享的基類子物件稱為虛基類。這種機制下,不論虛基類在繼承體系中出現了多少次,在派生類中都只包含唯一乙個共享的虛基類子物件。
舉例說明:
在過去,科學界對大熊貓屬於raccoon科還是bear科爭論不休。為了如實地反映這種爭論,我們可以對panda類進行修改,令其同時繼承bear和raccoon。此時,為了避免賦予panda兩份zooanimal的子物件,我們將bear和raccoon繼承zooanimal的方式定義為虛繼承。
zooanimal
/ \
bear raccoon endangered
\ | /
\ | /
\ | /
panda
注意:虛派生只影響從指定了虛基類繼承的派生類中進一步派生出的類,它不會影響派生類本身。
**實現
將上述舉例用**表示,如下:
//指定虛基類的方式是在派生列表中新增關鍵字virtual:
class raccoon: public virtual zooanimal
;class bear: public virtual zooanimal
;//如果某個類指定了虛基類,則該類的派生類按常規方式進行:
class panda: public bear,
public raccoon,
public endangered
;
建構函式與虛繼承
在虛派生中,虛基類是由最低層的派生類初始化的。以我們的程式為例,當建立panda物件時,由panda的建構函式獨自控制zooanimal的初始化過程。
含有虛基類的物件的構造順序與一般的順序稍有區別:首先使用提供給最低層派生類建構函式的初始值初始化該物件的虛基類子部分,接下來按照直接基類在派生列表中出現的次序依次對其進行初始化。
例如,當我們建立乙個panda物件時:
如果panda沒有顯示第初始化zooanimal基類,則zooanimal的預設建構函式將被呼叫。如果zooanimal沒有預設建構函式,則**將發生錯誤。
虛基類總是先於非虛基類構造,與它們在繼承體系中的次序和位置無關
建構函式與析構函式的次序
乙個類可以有多個虛基類。此時,這些虛的子物件按照它們在派生列表中出現的順序從左向右依次構造。例如,在下面這個稍顯雜亂的teddybear派生關係中有兩個虛基類:toyanimal是直接虛基類,zooanimal是bear的虛基類:
class character ;
class bookcharacter : public character ;
class toyanimal ;
class teddybear : public bookcharacter,
public bear, public virtual toyanimal
;/*編譯器按照直接基類的宣告順序對其依次進行檢查,以確定其中是否含有虛基類。如果有,則先構造基類,然後按照宣告的順序逐一構造其他非虛基類。因此,要想建立乙個teddybear物件,需要按照如下次序呼叫這些建構函式:
*/zooanimal(); //bear的虛基類
toyanimal(); //直接虛基類
character(); //第乙個非虛基類的間接基類
bookcharacter(); //第乙個直接非虛基類
bear(); //第二個直接非虛基類
teddybear(); //最低層的派生類
物件的銷毀順序與構造順序正好相反,首先銷毀teddybear部分,最後銷毀zooanimal部分。 繼承知識點總結
一 繼承的定義 1.繼承是物件導向的主要特徵 此外還有封裝和多型 之一,它使得乙個類可以從現有類中派生,而不必重新定義乙個新類。2.繼承的實質就是用已有的資料型別建立新的資料型別,並保留己有資料型別的特點,以舊類為基礎建立新類,新類包含了舊類的資料成員和成員函式,並且可以在新類中新增新的資料成員和成...
C 知識點53 虛繼承
二 虛繼承 1.概念 預設情況下,c 的派生列表中不允許同乙個基類出現兩次,但是,如果兩個基類都繼承了同乙個類a,那麼兩個基類派生出的子類就會包含兩次類a的部分 為了解決上述問題,c 中就出現了虛繼承,通過虛繼承,無論虛基類在整個繼承鏈 現了多少次,子類中都只出現一次。示例class animal ...
虛函式知識點總結
一 虛函式的定義 c 中的虛函式時定義在基類中的函式,子類必須對其進行覆蓋。在類中宣告 無函式體的形式叫做宣告 虛函式的格式 virtual void display 二 虛函式的作用 1.定義子類物件,並且可以呼叫物件中未被子類覆蓋的積累函式a同時在a中,又呼叫了已被子類覆蓋的基類函式b。這樣的話...