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 SubClassA") {
cout<<"<<SubClassA::SubClassA" << endl;
cout<<">>SubClassA::SubClassA" << endl;
}
};
class SubClassB: public Base
{
public:
SubClassB():Base("From SubClassB") {
cout<<"<<SubClassB::SubClassB" << endl;
cout<<">>SubClassB::SubClassB" << endl;
}
};
class Leaf: public SubClassA, public SubClassB
{
public:
Leaf():SubClassA(), SubClassB(), Base("From Leaf") {
cout << "<<Leaf::Leaf" << endl;
cout << ">>Leaf::Leaf"<< endl;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Leaf myleaf;
myleaf.f_PureVirtualBase();
return a.exec();
}
- If I comment the call to f_PurevirtualBase it compiles but I have a warning that virtual base 'Base' inaccessible in 'Leaf' due to ambiguity If I uncomment this call: I get this error : request for member 'f_PureVirtualBase' is ambiguous
- If I prefix this call by the class name (myleaf.SubClassA::f_PureVirtualBase() then it works, but something is obviously wrong as there are 2 Base contained in the Leaf Object).
Any hint?
More info to answer comments
My target architecture is slightly more complex that the sample I provided in the original question:
PureVirtualBase(SDK)
|
Base(SDK)
|
--SubClassA
--SubClassB(SDK)
--SubClassC(SDK)
--SubClassD(SDK)
LeafOne : inherits from SubClassA and SubClassB(SDK)
LeafTwo : inherits from SubClassA and SubClassC(SDK)
LeafThree : inherits from SubClassA and SubClassD(SDK)
SubClassA is my own private code. It provides custom functions. It should be able to be treated like a Base instance by SDK methods. This class won't be instantiated but it is here to be able to handle LeafOne, LeafTwo and LeafThree in the same when performing some treatment.