C ++ Diamond inheritance solution without virtual inheritance
I have the following diamond class structure that does not compile:
class Base{
int a;
public:
virtual void doSomething();
};
class NotMineToTouch : public Base {};
class MyParentClass : public Base {};
class EvilDiamond : public NotMineToTouch, public MyParentClass {};
// I need these methods (that I cannot necessarily edit) to work for an EvilDiamond
void processBase (Base* b) { b->doSomething; /*...*/} // Cannot edit
void processParent (MyParentClass* p) { p->doSomething; /*...*/} // Can edit
void processNotMine (NotMineToTouch* n) { n->doSomething; /*...*/} // Cannot edit
I know the normal solution is to practically inherit from Base
; however, I am not allowed to modify NotMineToTouch
(or Base
). Is there any other solution? I can change MyParentClass
, and EvilDiamond
in his pleasure; however, EvilDiamond
must inherit from MyParentClass
and NotMineToTouch
, but MyParentClass
must inherit from Base
and cannot inherit from EvilDiamond
.
source to share
I challenge the following statement:
EvilDiamond must inherit from MyParentClass and NotMineToTouch
Perhaps you can do something along these lines (depending on your architecture):
class EvilDiamond;
class NotMineToTouchImpl : public NotMineToTouch {
EvilDiamond* tgt_;
public:
NotMineToTouchImpl(EvilDiamond* tgt) : tgt_(tgt) {}
... implement NotMineToTouch here, using tgt_ where you would have used this
};
class MyParentClassImpl : public MyParentClass {
EvilDiamond* tgt_;
public:
MyParentClassImpl(EvilDiamond* tgt) : tgt_(tgt) {}
... implement Base here, using tgt_ where you would have used this
};
class EvilDiamond {
friend class NotMineToTouchImpl;
friend class MyParentClassImpl;
// Creating permanent instances of the API classes
// may or may not be appropriate in your case.
NotMineToTouchImpl nmti_;
MyParentClassImpl pci_;
public:
EvilDiamond () : nmti_(this), pci_(this) {}
NotMineToTouchImpl* getAsNotMineToTOuch() {return &nmti_;}
MyParentClassImpl * getAsParentClass() {return &pci_;}
};
source to share
You don't have a diamond as you are not using virtual inheritance.
you have some "Y" inheritance ( EvilDiamond
has 2 Base
).
Without changing the classes, you can add overloads to tell the compiler what to do:
void processBase (EvilDiamond* evil) {
processBase(static_cast<NotMineToTouch*>(evil)); // Use NotMineToTouch::Base
processBase(static_cast<MyParentClass*>(evil)); // Use MyParentClass::Base
}
source to share