2016-07-19 29 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. 
};