Alex Rivera | Logout

How to create a diamond inheritance hierarchy when I cannot modify all of the base classes?

Asked 2012-04-05T10:39:44.287
12

I am having a hard time with a dreaded diamond problem. For a reminder, here is the classical class hierarchy of this problem:

    B
   / \
 C1   C2
   \ /
    D

To solve it, the standard solution is to make C1 and C2 use virtual inheritance to inherit from B.

My problem is that B and C1 are from an SDK that I cannot modify. Example below where I cannot make SubClassB inherit virtually from Base. Classes: PureVirtualBase, Base and SubClassB are from the SDK I use. I cannot modify them. SubClassA and Leaf are my custom classes. I can change them.

     PureVirtualBase(SDK)
           |
        Base(SDK)
       /        \
 SubClassA   SubClassB(SDK)
       \        /
          Leaf

In such a situation where SubClassB cannot be changed to use virtual inheritance from Base. How what should so that:

  • Leaf instance only contains one Base
  • Avoid the ambiguity when trying to access functions defined pure virtual in PureVirtualBase and implemented in Base
class PureVirtualBase
{
public:
    PureVirtualBase()
    {
        cout<<"<<PureVirtualBase::PureVirtualBase" << endl;
        cout<<">>PureVirtualBase::PureVirtualBase" << endl;
    }
    virtual int f_PureVirtualBase()=0;
};
class Base : public PureVirtualBase
{
public:
    Base(std::string id) {
        cout<<"<<Base::Base:"<<id << endl;
        m_id=id;
        cout<<">>Base::Base:"<<m_id << endl;
    }
    virtual int f_PureVirtualBase() {
       cout<<"Base::f_PureVirtualBase" << endl;
       return 1;
    }
private:
    std::string m_id;
};
class SubClassA:  public virtual Base
{
public:
    SubClassA(): Base("From
Edit
Report

1 Answer

1

If you're really stuck with these design constraints I'd definitely look to subclassing from B directly with an class that took C1 and C2 as composite components. Unfortunately that requires manually mirroring their interface (hopefully it's small or you can limit it to what you need) and proxying through to the subcomponents. It's not pretty, but unless you can enforce some give on the design elsewhere, then you're not really left with much choice.

One disadvantage of course is that you don't have the type identity you're looking for (the subclass won't satisfy "isa" of C1 or C2) which may be enough to blow this approach out of the water.

It's not pretty. But I expect that given your constraints it might be the "least bad" solution.

answered 2012-04-05T13:34:14.023

Your Answer