2013-01-31 25 views
1

我的理解是,在E對象中,C AND D對象分別由c和d引用。但我無法理解爲什麼d.set_c('b')未能將B.m_c初始化爲'b',其中c.set_n(3)能夠將A.m_n的值更改爲3.輸出成爲a2a3而不是a2b3

#include <iostream> 

    class A 
    { 
    public: 
     A(int n = 2) : m_n(n) {} 

    public: 
     int get_n() const { return m_n; } 
     void set_n(int n) { m_n = n; } 

    private: 
     int m_n; 
    }; 

    class B 
    { 
    public: 
     B(char c = 'a') : m_c(c) {} 

    public: 
     char get_c() const { return m_c; } 
     void set_c(char c) { m_c = c; } 

    private: 
     char m_c; 
    }; 

    class C 
     : virtual public A 
     , public B 
    { }; 

    class D 
     : virtual public A 
     , public B 
    { }; 

    class E 
     : public C 
     , public D 
    { }; 

    int main() 
    { 
     E e; //object of E is created 
     C &c = e; //c is used to refrence C object in E Object 
     D &d = e; //c and d has same inheritance structure 
     std::cout << c.get_c() << d.get_n(); 

     c.set_n(3); 
     d.set_c('b'); 
     std::cout << c.get_c() << d.get_n() << std::endl; 

     return 0; 
    } 
+1

請你能選擇一個更有用的標題? –

回答

0

變化

, public B 

, virtual public B 

得到輸出a2b3

在您的示例中,E實例包含單獨的B實例。

3

讓我們看看你的類結構,如果您創建的E一個實例,你最終會與對象的層次結構看起來像這樣:

class B class A class B 
    \  /\  /
     \ / \ /
     \ / \ /
     class C class D 
      \  /
      \ /
      \ /
      class E 

你看也有B兩個實例,但只有一個A的實例。這是因爲虛擬繼承。 CD都使用虛繼承從A繼承,因此您的e中只有一個A實例。

現在讓我們看一下用戶的代碼:

E e; 
C &c = e; // reference C in the object hierarchy of E 
D &d = e; // reference D in the object hierarchy of E 

c.set_n(3); // set the value in the only instance of A in E 
d.set_c('b'); // set the value of one of the two instances of B in your e 

std::cout << c.get_c(); // print the value in the other instance of B in e 
         // not the one you set before 
std::cout << d.get_n(); // print the value of the only instance of A in e 
         // this got changed before 
+0

我一直在編程C++兩年,從未想過這件事。你先生,應該得到讚揚和謝謝。 謝謝。 – Xathereal

1

類的對象E含有CD子對象而這又各自含有B子對象。由於沒有關於B的虛擬繼承,因此每個CD都包含它們自己的B的副本。

d.set_c()然後是指包含在,雖然c.get_c()是指包含在CB,這是獨立於一個在D的,因此並沒有改變D和更新B

對於A類和其成員n沒有這樣的問題,因爲使用虛擬繼承。這確保在類E的最後一個對象中,只有一個子對象A被大家使用,無論通過哪個「路徑」訪問它。