C++中的虛繼承的構造

dongyu2013發表於2014-03-27

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

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

在這裡有四個類:Point ,PointA,PointB,DerivedPoint。我給出標頭檔案,不用給出原始檔了:

  1. class Point    
  2. {  
  3. public:  
  4.     Point();  
  5.     virtual ~Point();  
  6.     int x,y;  
  7.   
  8. };  


 

  1. #include"Point.h"  
  2. class PointA :public virtual Point   
  3. {  
  4. public:  
  5.     PointA();  
  6.     virtual ~PointA();  
  7.     int a;  
  8.   
  9. };  


 

  1. #include"Point.h"  
  2. class PointB  :public virtual Point   
  3. {  
  4. public:  
  5.     PointB();  
  6.     virtual ~PointB();    
  7.     int b;  
  8.   
  9. };  


 

  1. #include"PointA.h"  
  2. #include"PointB.h"  
  3. class DerivedPoint :public PointA,public PointB   
  4. {  
  5. public:  
  6.     DerivedPoint();  
  7.     virtual ~DerivedPoint();  
  8.     int d;  
  9.   
  10. };  


PointA和PointB虛繼承Point,DerivedPoint繼承自PointA與PointB。

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

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

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

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

特殊的初始化語意

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

 

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

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

  1. class Point    
  2. {  
  3. public:  
  4.     Point();  
  5.     Point(int x,int y){this->x=x;this->y=y;};  
  6.     virtual ~Point();  
  7.     int x,y;  
  8.   
  9. };  


 

  1. #include"Point.h"  
  2. class PointA :public virtual Point   
  3. {  
  4. public:  
  5.     PointA();  
  6.     PointA(int x,int y,int a):Point(x,y),a(a)  
  7.     {};  
  8.     virtual ~PointA();  
  9.     int a;  
  10.   
  11. };  


 

  1. #include"Point.h"  
  2. class PointB  :public virtual Point   
  3. {  
  4. public:  
  5.     PointB();  
  6.     PointB(int x,int y,int b):Point(x,y){this->b=b;};  
  7.     virtual ~PointB();    
  8.     int b;  
  9.   
  10. };  


 

  1. #include"PointA.h"  
  2. #include"PointB.h"  
  3. class DerivedPoint :public PointA,public PointB   
  4. {  
  5. public:  
  6.     DerivedPoint();  
  7.     DerivedPoint(int x,int y,int a,int b,int d):PointA(x,y,a),PointB(x,y,b),Point(x,y),d(d){};  
  8.     virtual ~DerivedPoint();  
  9.     int d;  
  10.   
  11. };  

 

在主函式中呼叫如下:

  1. #include  
  2. #include "DerivedPoint.h"  
  3. using namespace std;  
  4.   
  5. void main()  
  6. {  
  7.     DerivedPoint pt(1,2,3,4,5);  
  8.   
  9.     cout<
  10.   
  11. }  


列印結果正常。

在這裡首先構造虛基類,再構造PointA,PointB,DerivedPoint。在PointA和PointB中構造虛基類的呼叫被忽略。如果在DrivedPoint的建構函式中不顯示呼叫Point的建構函式,就呼叫Point的預設建構函式,如果Point沒有預設的建構函式,程式碼出錯。

 

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

 

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29012686/viewspace-1131012/,如需轉載,請註明出處,否則將追究法律責任。

相關文章