这是否存在此代码的已定义行为,该行为通过基类指针删除派生类?

Omn*_*ous 2 c++

此代码是否导致定义的行为?

class A {
    int x;
};
class B {
    short y;
};
class C {
    double z;
};

class D : public A, public B, public C {
    float bouncy;
};

void deleteB(B *b) {
    delete b;
}

void is_it_defined() {
    D *d = new D;
    deleteB(d);

    B *b = new D;  // Is this any different?
    delete b;
}
Run Code Online (Sandbox Code Playgroud)

如果没有定义,为什么不呢?如果是,它定义的是什么以及为什么?最后,如果定义了实现,您能举例说明一个常见的实现可能会定义行为吗?

ice*_*ime 6

引用草药Sutter:

如果可以通过基类接口以多态方式执行删除,则它必须虚拟地运行并且必须是虚拟的.实际上,语言需要它 - 如果你在没有虚拟析构函数的情况下删除多态,你就会召唤出"未定义行为"的可怕幽灵.

在您的示例中,两者delete都是通过基类指针执行的,并产生未定义的行为.标准5.3.5(删除):

在第一个替代(删除对象)中,如果操作数的静态类型与其动态类型不同,则静态类型应为操作数的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.

这里,两者都delete作用于静态类型,B而操作数的动态类型是D.