C 中的虛繼承

2021-08-07 20:49:59 字數 2665 閱讀 4175

注意:虛基類的建構函式一定是最先呼叫

多繼承中被當做基類來虛繼承的類是虛基類。

虛基類:使用關鍵字virtual繼承的基類。即使同一類在層次中作為虛基類出現多次,派生類物件中虛基類部分也只出現一次。在非虛基類中,建構函式只能初始化自己的直接基類,當對乙個類進行虛繼承的時候,由最底層的派生類初始化那個類,因此最底層的派生類應包含用於其他所有虛父類的初始化式。

在這裡有四個類:point ,pointa,pointb,derivedpoint。我給出標頭檔案,不用給出原始檔了:

[cpp]view plain

copy

class

point    

;  

[cpp]view plain

copy

#include"point.h"

class

pointa :

public

virtual

point   

;  

[cpp]view plain

copy

#include"point.h"

class

pointb  :

public

virtual

point   

;  

[cpp]view plain

copy

#include"pointa.h"

#include"pointb.h"

class

derivedpoint :

public

pointa,

public

pointb   

;  

pointa和pointb虛繼承point,derivedpoint繼承自pointa與pointb。

假定通過多個派生路徑繼承名為x的成員,有下面三種可能性:

1.如果在每個路徑中x表示同乙個虛基類成員,則沒有二義性,因為共享該成員的單個例項。

2.如果在某個路徑中x為虛基類成員,而在另一路徑中x是後代派生類成員,也沒有二義性------特定派生類例項的優先順序高於共享虛基類例項。

3.如果沿每個繼承路徑x表示後代派生類的不同成員,則該成員的直接訪問是二義性的。

特殊的初始化語意

從具有虛基類的類繼承的類對初始化進行了特殊的處理。在虛派生中由最底層派生類的建構函式初始化虛基類

雖然由最底層派生類初始化虛基類,但是任何直接或者間接繼承虛基類的類一般也必須為該基類提供自己的初始化式。只要可以建立虛基類派生類型別的物件,該類就必須初始化自己的虛基類部分,這些初始化式只在建立中間型別物件時使用。

有了以上的規則,我的類就應該如下寫:

[cpp]view plain

copy

class

point    

;  virtual

~point();  

intx,y;  

};  

[cpp]view plain

copy

#include"point.h"

class

pointa :

public

virtual

point   

;  virtual

~pointa();  

inta;  

};  

[cpp]view plain

copy

#include"point.h"

class

pointb  :

public

virtual

point   

;  virtual

~pointb();    

intb;  

};  

[cpp]view plain

copy

#include"pointa.h"

#include"pointb.h"

class

derivedpoint :

public

pointa,

public

pointb   

;  virtual

~derivedpoint();  

intd;  

};  

在主函式中呼叫如下:

[cpp]view plain

copy

#include

#include "derivedpoint.h"

using

namespace

std;  

void

main()    

列印結果正常。

在這裡首先構造虛基類,再構造pointa,pointb,derivedpoint。在pointa和pointb中構造虛基類的呼叫被忽略。如果在drivedpoint的建構函式中不顯示呼叫point的建構函式,就呼叫point的預設建構函式,如果point沒有預設的建構函式,**出錯。

C 中的虛繼承

如果乙個派生類從多個基類派生,而這些基類又有乙個共同 的基類,則在對該基類中宣告的名字進行訪問時,可能產生二義性 如果在多條繼承路徑上有乙個公共的基類,那麼在繼承路徑的某處 匯合點,這個公共基類就會在派生類的物件中產生多個基類子物件 要使這個公共基類在派生類中只產生乙個子物件,必須對這個基類 宣告為...

C 中虛繼承

虛繼承和虛函式是完全無相關的兩個概念。虛繼承是解決c 多重繼承問題的一種手段,從不同途徑繼承來的同一基類,會在子類中存在多份拷貝。這將存在兩個問題 其一,浪費儲存空間 第二,存在二義性問題,通常可以將派生類物件的位址賦值給基類物件,實現的具體方式是,將基類指標指向繼承類 繼承類有基類的拷貝 中的基類...

C 中虛繼承

在c 中多繼承時很容易產生命名衝突,即使我們很小心地將所有類中的成員變數和成員函式都命名為不同的名字,命名衝突依然有可能發生,比如典型的是菱形繼承,如下圖所示 類 a 派生出類 b 和類 c,類 d 繼承自類 b 和類 c,這個時候類 a 中的成員變數和成員函式繼承到類 d 中變成了兩份,乙份來自 ...