C++ 是不是;删除“;如何正确处理多态性?
我知道如果第二行没有虚拟析构函数,它将调用基类的析构函数,如果它有虚拟析构函数,则调用派生类的析构函数,但它将C++ 是不是;删除“;如何正确处理多态性?,c++,virtual-destructor,C++,Virtual Destructor,我知道如果第二行没有虚拟析构函数,它将调用基类的析构函数,如果它有虚拟析构函数,则调用派生类的析构函数,但它将delete正确地释放内存(比如BaseClass的对象占用8字节的空间,而DerivedClass的一个12字节-它将释放8或12字节)在这两种情况下都要删除该对象?如果它有一个虚拟的析构函数,那么该对象当然会被销毁,内存也会按预期被释放。如果它没有虚拟析构函数,则行为未定义 如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,并且静态类型应具有虚拟
delete
正确地释放内存(比如BaseClass
的对象占用8字节的空间,而DerivedClass
的一个12字节-它将释放8或12字节)在这两种情况下都要删除该对象?如果它有一个虚拟的
析构函数,那么该对象当然会被销毁,内存也会按预期被释放。如果它没有虚拟
析构函数,则行为未定义
如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,并且静态类型应具有虚拟析构函数或行为未定义
因此,试图推断内存是否将被完全释放是没有任何意义的。程序可以对内存执行任何操作。如果析构函数不是虚拟的,
delete
将不会删除派生类
我试过这个:
BaseClass * p = new DerivedClass();
delete p;
请注意没有
Killing-derived.
您熟悉malloc
/free
语义吗?关于:“调用基类的析构函数”-可能。如果通过指向基类型的指针删除派生类型的对象,并且基类型没有虚拟析构函数,则行为未定义。它可能会调用基类的析构函数,但不需要这样做。@NPS注意,值得一提的是,如果您在堆栈上创建了DerivedClass对象(即-DerivedClass d;),那么基类Dtor是虚拟的还是非虚拟的根本不重要—它们两个(都是Dtor)将按照与它们的构造相反的顺序调用(即-DerivedClass和than BaseClass)。据我所知,析构函数只是在程序实际销毁对象之前进行手动清理的一种方法。所以,如果我错了,请纠正我,但我认为这段代码证明不了什么。如果在堆上分配内存(就像使用new
分配内存一样)。如果析构函数没有被调用,我认为可以安全地说内存也没有被释放。如果您感兴趣:
#include<iostream>
using namespace std;
class Base {
public:
Base() {
cout<<"Creating base."<<endl;
}
~Base() {
cout<<"Killing base."<<endl;
}
};
class Derived: public Base {
public:
Derived() {
cout<<"Creating derived."<<endl;
}
~Derived() {
cout<<"Killing derived."<<endl;
}
};
int main() {
Base *p = new Derived();
delete p;
return 0;
}
Creating base.
Creating derived.
Killing base.