0

I have this annoying multiple-inheritance diamond of doom with a complicated twist (We're talking about MS COM objects, a detail which will be relevant later) -

  • Assume an abstract class (interface) A which has some pure virtual methods.
  • Another abstract class (another interface) B is derived from A and expands it with more pure virtual methods.
  • Class C is derived from class A and implements all of its abstract methods.
  • Class D is currently derived from class B, implementing all abstract methods from both A and B.

Right now I have two classes C, D with a lot of copy-pasted code (since most of the required interface resides in class A). I'd like to avoid this by having D inherit from C, however D also inherits from B, which creates a classic diamond of doom issue.

I know this can be solved with virtual inheritance, but here's the twist in the plot: Classes A and B are COM interfaces, defined in an SDK which I cannot modify (i.e. "A.h" and "B.h" are read only). The inheritance from A to B is not virtual and this cannot be modified. I can modify classes C and D, but they must completely adhere to the defined interfaces.

I'd appreciate any creative ideas on how to overcome this.

Dan
  • 261
  • 2
  • 8
  • 1
    Consider using composition instead. – V. Kravchenko Jul 19 '16 at 11:33
  • The real problem isn't even a "Diamond of Doom". You're dealing with COM, which has only single inheritance. Having D inherit from C breaks that, regardless of how you do it. – MSalters Jul 19 '16 at 11:54
  • Eventually indeed used composition. Forced me to write a proxy function for each function in A but at least it worked. – Dan Jul 26 '16 at 15:43

2 Answers2

1

I'm assuming from the details of the question, that the problem you have is with the functions and not with some member variables of A (which seems to be just an interface).

In that case here are two options that spring to mind.

1) have D own a C rather than inherit from it.

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

or inherit privately from C

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

Where FA() is some pure virtual function in A

Both cases involve defining a function to implement FA in D, but the actual implementation detail is not duplicated.

ROX
  • 1,256
  • 8
  • 18
0

The ATL way of resolving this situation:

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.
};
Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85