如果父类的析构函数不是虚拟的,但子类没有额外的成员,那么使用父类的析构函数是否安全?
class A{
~A();
protected:
int i;
};
class B: public A{
}
A *x = new B; delete x;
如果父类的析构函数不是虚拟的,但子类没有额外的成员,那么使用父类的析构函数是否安全?
class A{
~A();
protected:
int i;
};
class B: public A{
}
A *x = new B; delete x;
简短的回答是否定的,这是不安全的。
这是不安全的,它是根据 §5.3.5 的未定义行为
5.3.5 删除[expr.delete]
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++。
为什么要冒险?
确保基类也被销毁的几个字节并不是什么大问题。
还可以防止内存泄漏。