Search code examples
c++sdkcommultiple-inheritancediamond-problem

C++ Diamond of Doom with external SDK


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.


Solution

  • 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.