带有外部SDK的C ++ Diamond of Doom

时间:2016-07-19 11:26:53

标签: c++ sdk com multiple-inheritance diamond-problem

我有这个烦人的多重继承钻石的厄运与复杂的扭曲(我们正在谈论MS COM对象,这个细节将在以后相关) -

  • 假设一个抽象类(接口)A,它有一些纯虚方法。
  • 另一个抽象类(另一个接口)B从A派生,并使用更纯的虚方法扩展它。
  • C类派生自A类,并实现其所有抽象方法。
  • D类目前来自B类,实现了A和B的所有抽象方法。

现在我有两个类C,D有很多复制粘贴的代码(因为大多数必需的接口都在A类中)。我想通过让D继承自C来避免这种情况,但是D也继承自B,它创造了一个经典的厄运问题钻石。

我知道这可以通过虚拟继承来解决,但是这里是图中的扭曲:类A和B是COM接口,在SDK中定义,我无法修改(即“Ah”和“Bh”是只读的) 。从A到B的继承不是虚拟的,不能修改。我可以修改类C和D,但它们必须完全遵循定义的接口。

我很欣赏有关如何克服这一点的任何创意。

2 个答案:

答案 0 :(得分: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()是A

中的一些纯虚函数

两种情况都涉及定义在D中实现FA的功能,但实际的实现细节不重复。

答案 1 :(得分: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.
};