C++ 无虚拟析构函数的继承

C++ Inheritance without virtual destructors

本文关键字:继承 析构函数 虚拟 C++      更新时间:2023-10-16

如果父类的析构函数不是虚拟的,但子类没有其他成员,那么使用父类的析构函数是否安全?

class A{
    ~A();
    protected:
        int i;
};
class B: public A{
}
A *x = new B; delete x;

这是不安全的,根据§5.3.5,它是未定义的行为

5.3.5 删除

3 在第一种备选方案(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应是要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义。在第二种备选方案(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义。

为什么它会中断一个例子是这样的:

class A
{
public:
    ~A();
protected:
    int i;
};
class B: public A
{
    virtual void dummy();
}
A *x = new B; delete x;

现在B有一个vtbl,因此对象布局不同。

顺便说一句:public class A是Java或其他语言,但不是C++。

简短的回答是否定的,这是不安全的。

为什么要冒险?

几个字节来确保基类也被销毁并不是那么大。

还可以防止内存泄漏。