C++ 在没有虚拟继承的情况下解决钻石继承
C++ Solving Diamond Inheritance Without Virtual Inheritance
我有以下菱形 class 无法编译的结构:
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
)。还有其他解决方案吗?我可以随意更改 MyParentClass
和 EvilDiamond
;但是,EvilDiamond
必须继承自 MyParentClass
和 NotMineToTouch
,并且 MyParentClass
必须继承自 Base
而不能继承自 EvilDiamond
.
我质疑以下论断:
EvilDiamond must inherit from MyParentClass and 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
有 2 Base
)。
在不改变你的 类 的情况下,你可以添加重载来指示编译器做什么:
void processBase (EvilDiamond* evil) {
processBase(static_cast<NotMineToTouch*>(evil)); // Use NotMineToTouch::Base
processBase(static_cast<MyParentClass*>(evil)); // Use MyParentClass::Base
}
我有以下菱形 class 无法编译的结构:
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
)。还有其他解决方案吗?我可以随意更改 MyParentClass
和 EvilDiamond
;但是,EvilDiamond
必须继承自 MyParentClass
和 NotMineToTouch
,并且 MyParentClass
必须继承自 Base
而不能继承自 EvilDiamond
.
我质疑以下论断:
EvilDiamond must inherit from MyParentClass and 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
有 2 Base
)。
在不改变你的 类 的情况下,你可以添加重载来指示编译器做什么:
void processBase (EvilDiamond* evil) {
processBase(static_cast<NotMineToTouch*>(evil)); // Use NotMineToTouch::Base
processBase(static_cast<MyParentClass*>(evil)); // Use MyParentClass::Base
}