class A
{
public:
int i;
~A()
{
std::cout << "~A" << std::endl;
}
};
class B: public A
{
public:
int k;
~B()
{
std::cout << "~B" << std::endl;
}
};
int main(int argc, char* argv[])
{
A* p = new B();
delete p;
return 0;
}
虽然基础析构函数不是虚拟的但上面不会导致内存泄漏,我知道原因。
但这是否是未定义的行为?
如果派生类没有指向其他动态数据,即使基础析构函数是非虚拟的,也不会有内存泄漏?
答案 0 :(得分:7)
是的。通过指向没有class
析构函数的基类的指针删除派生virtual
的对象是教科书UB。
<强> 5.3.5 / 3:强>
在第一个替代(删除对象)中,如果是静态类型的 操作数与其动态类型不同,静态类型应为a 操作数的动态类型的基类和静态类型 有一个虚拟析构函数或行为未定义。在第二 替代(删除数组)如果要对象的动态类型 删除与其静态类型不同,行为未定义.73)
因为它是未定义的行为,所以猜测代码是否会泄漏是没有意义的。只是尝试修复代码而不是预测结果。
答案 1 :(得分:4)
是的,因为静态类型(此处为A
)与动态类型(示例中为B
)不同,并且没有virtual
析构函数,所以它是UB。
5.3.5 / 2(C ++ 11中的5.3.5 / 3):
在第一个替代(删除对象)中,如果操作数的静态类型与其动态类型不同,则 static类型应该是操作数的动态类型的基类,静态类型应该是虚拟的 析构函数或行为未定义。