关于c ++:这个代码是否有定义的行为,通过基类指针删除派生类?


Is this there a defined behavior for this code that deletes a derived class through a base class pointer?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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;
}

如果没有定义,为什么不呢?如果是,它定义了要做什么,为什么?最后,如果它是实现定义的,您能举一个例子说明一个公共实现可能定义行为是什么吗?


引用药草缝合线:

If deletion can be performed
polymorphically through the base class
interface, then it must behave
virtually and must be virtual. Indeed,
the language requires it - if you
delete polymorphically without a
virtual destructor, you summon the
dreaded specter of"undefined
behavior".

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

In the first alternative (delete
object), if the static type of the
operand is different from its dynamic
type, the static type shall be a base
class of the operand’s dynamic type
and the static type shall have a
virtual destructor or the behavior is
undefined.

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


B没有虚拟析构函数,它应该有。


这都与虚拟析构函数有关吗?看看这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A
{
    int x;

public:
    virtual void fun()
    {
        return;
    }
};

class D : public A
{
    float bouncy;
};

void is_it_defined()
{

    A *b = new D;  // it`s ok!
    delete b;
}

你看见了吗?没关系。指针B可以正确删除。所以,只需要一个卵黄功能来激活多态性。