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

.

+3


source to share


2 answers


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_;}
};

      

+3


source


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
}

      

+2


source







All Articles