2016-07-19 28 views
0

我有厄運的這惱人的多重繼承的鑽石有一個複雜的扭曲(我們談論的是MS COM對象,這將是相關的後一個細節) -末日的C++鑽石與外部SDK

  • 假設抽象類(接口)A有一些純粹的虛擬方法。
  • 另一個抽象類(另一個接口)B派生自A,並用更純的虛擬方法擴展它。
  • C類從A類派生並實現了它的所有抽象方法。
  • 類d當前從B類衍生的,實施從A和B的所有的抽象方法

現在我有兩個類C,d與大量複製粘貼代碼(因爲大多數的所需的接口駐留在A類中)。我想通過從C繼承D來避免這種情況,但是D也繼承了B,它創建了厄運問題的經典鑽石。我知道這可以通過虛擬繼承來解決,但這裏是曲線中的扭曲:類A和B是COM接口,在我無法修改的SDK中定義(即「Ah」和「Bh」是隻讀)。從A到B的繼承不是虛擬的,這是不能修改的。我可以修改類C和D,但它們必須完全遵守定義的接口。

我很感激任何有關如何克服這一點的創意。

+1

考慮使用替代組成。 –

+0

真正的問題甚至不是「毀滅之鑽」。你正在處理只有單一繼承的COM。不管你是怎麼做的,從C繼承D都會打破這一點。 – MSalters

+0

最終確實使用的組成。強迫我爲A中的每個函數編寫代理函數,但至少它工作正常。 – Dan

回答

1

我假設從問題的細節,你有問題是與功能,而不是一些A的成員變量(這似乎只是一個接口)。

在這種情況下,這裏有兩個選項是值得思考的。

1)有D擁有C而不是從它繼承。

class D : public B 
{ 
    public: 
    virtual int FA() 
    { 
     return m_c.FA(); 
    } 
    private: C m_c; 
}; 

或繼承私下選自C

class D : public B, private C 
{ 
    public: 
    virtual int FA() 
    { 
     return C::FA(); 
    } 
}; 

其中fa()是在一個

一些純虛函數兩種情況涉及定義的函數在d實現FA,但實際實施細節不重複。解決這種情況的

+0

鑑於'A'是Microsoft COM接口,我們知道它不能有成員數據。 – MSalters

0

The ATL方式:

template <typename Itf> 
class IAImpl : public Itf { 
    // Implement IA methods 
}; 

class C : public IAImpl<IA> {}; 

class D : public IAImpl<IB> { 
    // Implement methods of IB that are in addition to IA. 
};