2012-04-14 142 views
1

我想不出在以下情況下會發生什麼:C++多重繼承

class MBase { 
    public: 
     MBase(int) {} 
     virtual char* vf() const = 0; 
     virtual ~MBase() {} 
}; 

class D1 : public MBase { //NOT VIRTUAL!!! 
    public: 
    D1() : MBase(1) {} 
    char* vf() const { return "D1"; } 
}; 

class D2 : virtual public MBase { 
    public: 
     D2() : MBase(2) {} 
     char* vf() const { return "D2"; } 
}; 

class Bottom : public D1, public D2 { 
    public: 
    char* vf() const { return "Bottom"; } 
} 

Base* b = new Bottom(); 

在D1和D2從MBASE幾乎繼承了鑽石的原始定義,但這裏只有一個。我們是否仍然在Bottom對象中有兩個單獨的子對象,因此最後一行不能編譯,因爲編譯器不知道要使用哪個子對象?

+1

你*嘗試了嗎? – 2012-04-14 17:04:51

回答

2

這在C++ 03標準的第10.1.4節中有規定。虛擬和非虛擬基礎是獨立的,所以每個基礎都會有一個。

這是很容易擴大你的例子來說明這一點:

class MBase { 
    public: 
     MBase(int arg) { cerr << "MBase::MBase(" << arg << ")\n"; } 
     virtual const char* vf() const = 0; 
     virtual ~MBase() {} 
}; 

class D1 : public MBase { //NOT VIRTUAL!!! 
    public: 
    D1() : MBase(1) {} 
    const char* vf() const { return "D1"; } 
}; 

class D2 : virtual public MBase { 
    public: 
     D2() 
     : MBase(2) // This doesn't get used in this example because 
        // it is the responsibility of the most-derived 
        // class to initialize a virtual base, and D2 isn't 
        // the most-derived class in this example. 
     { 
     } 
     const char* vf() const { return "D2"; } 
}; 

class Bottom : public D1, public D2 { 
    public: 
    Bottom() 
    : MBase(5) // D1 and D2 default constructors are called implicitly. 
    { 
    } 
    const char* vf() const { return "Bottom"; } 
}; 

int main(int argc,char **argv) 
{ 
    Bottom b; 
    return 0; 
} 

輸出:

MBase::MBase(5) 
MBase::MBase(1) 
+0

爲什麼D2的構造函數從未被調用? – Bober02 2012-04-14 17:57:51

+0

@ Bober02:D2構造函數被調用,但D2不調用虛擬基類的構造函數,即使它看起來像它一樣。我在答覆中添加了一些解釋。 – 2012-04-14 18:05:01

1

我覺得你的問題是與此類似的......基本上,每個客體都有自己的MBASE類的基本對象...

Diamond inheritance

雷加rds,Erwald