C++解决没有虚拟继承的钻石继承问题

C++ Solving Diamond Inheritance Without Virtual Inheritance

本文关键字:继承 问题 钻石 虚拟 解决 C++      更新时间:2023-10-16

我有以下无法编译的钻石类结构:

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

我知道正常的解决方案是从Base继承;但是,我不允许更改NotMineToTouch(或Base(。 有没有其他解决方案? 我被允许随心所欲地改变MyParentClassEvilDiamond;但是,EvilDiamond必须继承MyParentClassNotMineToTouchMyParentClass必须继承Base,不能继承EvilDiamond

我挑战以下断言:

EvilDiamond 必须继承自 MyParentClass 和 NotMineToTouch

您可以按照以下思路执行一些操作(取决于您的体系结构(:

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

你没有钻石,因为你不使用虚拟继承。
您目前有一些"Y">继承(EvilDiamond有 2Base(。

在不更改类的情况下,您可以添加重载来指示编译器要做什么:

void processBase (EvilDiamond* evil) {
processBase(static_cast<NotMineToTouch*>(evil)); // Use NotMineToTouch::Base
processBase(static_cast<MyParentClass*>(evil));  // Use MyParentClass::Base
}