【发布时间】:2017-12-09 23:43:43
【问题描述】:
我有以下无法编译的菱形类结构:
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。
【问题讨论】:
-
我只收到警告而不是错误。你能给我们你得到的实际编译器错误或发布重现问题的代码吗?顺便说一句,如果您不使用虚拟继承,它就不是钻石。虚拟继承是将两个基础合并为一个,如果您在图表中绘制菱形形状。
-
我们在 Bases 和 MyParentClass 的其他地方调用了虚拟方法 getA()(在代码中我并不总是被允许更改)。可能不是钻石继承,但肯定是钻石问题(见标签上的说明)。当我在 EvilDiamond 上调用 getA() 时出现编译器错误:错误:对成员“getA”的请求不明确注意:候选者是:virtual int Base::getA() 注意:virtual int Base::getA()
-
传递对象时不能转换为正确的类型吗?
-
Passer By - 我不能将一个对象转换为它不是的东西(因此我需要多重继承)。我认为没有理由强制转换——如果我的对象子类化了一个基类,我可以将它传递到需要该类指针的地方。这不是过载问题。
-
以下代码会给出该错误
void processEvilDiamond (EvilDiamond* n) { n->doSomething(); }解决方案是指定您想要的:void processEvilDiamond (EvilDiamond* n) { n->MyParentClass::doSomething(); }
标签: c++ c++11 multiple-inheritance diamond-problem