2012-08-27 21 views
0

我的問題是有關的結構如下: enter image description here雙遺產:

抽象水平只是在這裏提供了「真正的」類(D1和D2)成員函數。由於需要高度優化,因此不存在虛擬性(抽象級別的析構函數受到保護)。在以下情況下,B0-C1-C2-D1是否完全可以正常工作:

  1. B0,C1和C2具有不同名稱的成員函數嗎?

  2. C1和C2具有相同名稱的功能(例如myFunction)?

  3. C1和C2和D1具有相同名稱的功能(例如myFunction)?

  4. B0和C2具有相同名稱但不包含C1的功能(例如myFunction)?

在每種情況下D1都會調用哪個版本的函數?

編輯:一個快速的代碼,以說明:

template<class CRTP> class A0 
{ 
    public: 
     void myfunction1(); 
    protected: 
     ~A0(); 
     double mymember; 
}; 

template<class CRTP> class B0 : public A0<CRTP> 
{ 
    public: 
     void myfunction2(); 
    protected: 
     ~B0(); 
}; 

template<class CRTP> class C1 : public B0<CRTP> 
{ 
    public: 
     void myfunction3(); 
    protected: 
     ~C1(); 
}; 

template<class CRTP> class C2 : public B0<CRTP> 
{ 
    public: 
     void myfunction4(); 
    protected: 
     ~C2(); 
}; 

class D1 : public C1<D1>, public C2<D1> 
{ 
    public: 
     void myfunction5(); 
}; 
+2

你的照片中沒有'D0'。很明顯,其他人會被這樣的設計所困惑,但是看起來你甚至感到困惑! :-) –

+0

謝謝。編輯:D0和D1 - > D1和D2 – Vincent

+0

繪圖很好,但它不如代碼有用。特別是,似乎一直到'C'級別的只有帶CRTP的模板,對嗎? –

回答

0

我不會說沒關係,除非你班上有A0B0兩次,儘管他們是不同的班級(B0<C1>B0<C2>)。除非你正在做一些專業,這很可能是not what you want

一個可能的解決方案,這將是something like this,從而消除了多重繼承:

template<class CRTP, class Base = B0<CRTP> > class C1 : public Base 
{ 
    public: 
     void myfunction3(); 
    protected: 
     ~C1(); 
}; 

template<class CRTP, class Base = B0<CRTP> > class C2 : public Base 
{ 
    public: 
     void myfunction4(); 
    protected: 
     ~C2(); 
}; 

class D1 : public C2<D1,C1<D1>> 
{ 
    public: 
     void myfunction5(); 
}; 

那麼,如果你想有一個鑽石在那裏,你能做到這一點沒有多個基類的實例?
不,因爲
a)正如我所說的基類是不同的,並且b)在C++虛擬繼承中只能用於具有vtable的類。

0

「完全確定」是有些主觀的,但所有的情況是該語言內明確定義。

您可能會遇到diamond inheritanceD1的問題。 如果它合適,您可以使用virtual inheritance使C1C2從共同基地繼承。對我們來說,猜測並不總是合適的。

1)

它們是不同的類,具有不同的方法,沒有衝突。

2)

有內C1C2沒有問題,但D1會出現問題。

3)

D1來定義它。將繼承myFunction調用將被外部遮蔽(無法訪問)。你可以從D1內部打電話給他們,如下所示:

struct D1 { 
    void myFunction() { 
    C1::myFunction(); 
    C2::myFunction(); 
    } 
} 

有了CRTP,這將會很煩人。我建議在類定義中使用typedefs,以保持您的理智。

4)

C1會有什麼函數B0給它。如果他們無法訪問,那麼如果你引用它們,你會得到一個編譯器錯誤。

坦率地說,我建議不要這種設計。把所有東西都分解成小的具體物體並組成它們。保持這個不會是一個項目,這將是一個職業。