具有多态性的"dreaded diamond"

"dreaded diamond" with polymorphism

本文关键字:dreaded diamond 多态性      更新时间:2023-10-16

我有以下代码:

class Base
{
    public:
        virtual void doSomething() = 0;
};
class BaseImpl : public virtual Base
{
    public:
       virtual void doSomething() {
       // something
       }
};
class BaseDerived: public virtual Base
{
    public:
       virtual void doSomething2() = 0;
};
class BaseDerivedImpl: public BaseImpl, public BaseDerived
{
    public:
       virtual void doSomething2(){
       // sonething2
       }
};

然后是

Base* b = new BaseImpl();
b->doSomething();          // fatal error at this line (not in the method, but in the method invocation)

问题是它甚至没有进入函数。

使用这样的层次结构有什么不对吗?

由于OP忽略了注释,让我在这里回答问题:

使用这样的层次结构有什么不对吗?

没有,什么事都没有。这是解决"可怕的钻石"问题的标准方法(实际上并没有那么可怕)。

然而,在这个例子中,菱形甚至没有发挥作用:

Base* b = new BaseImpl();

BaseImpl直接来源于Base,所以你有标准的单继承。您的代码的行为就像根本没有定义BaseDerivedBaseDerivedImpl一样。你可以把它们注释掉,但程序还是会崩溃。

然后在这个实例上调用doSomething,它崩溃了。doSomething的实现如下:

// something

因此,我的结论是// something导致崩溃,但如果没有看到该方法的实现,则无法判断。