“删除”是不是适用于多态性? [复制]
Posted
技术标签:
【中文标题】“删除”是不是适用于多态性? [复制]【英文标题】:Does "delete" work properly with polymorphism? [duplicate]“删除”是否适用于多态性? [复制] 【发布时间】:2013-05-06 02:05:01 【问题描述】:BaseClass * p = new DerivedClass();
delete p;
我知道如果基类没有虚拟析构函数,第二行将调用基类的析构函数,如果有,则调用派生类的析构函数,但 delete
会正确释放内存(假设为 BaseClass
' s 对象占用 8 个字节的空间,DerivedClass
的一个 12 - 它会释放 8 个或 12 个字节)并在任何一种情况下都摆脱该对象?
【问题讨论】:
你熟悉malloc
/free
语义吗?
Re: “调用基类的析构函数”——也许吧。如果通过指向基类型的指针删除派生类型的对象,并且基类型没有虚拟析构函数,则行为未定义。它可能会调用基类的析构函数,但这不是必须的。
@NPS 请注意,值得一提的是,如果您在堆栈上创建了 DerivedClass 对象(即 - DerivedClass d;),那么 BaseClass Dtor 是否为虚拟并不重要- 它们中的两个(都是 Dtor 的)将按照与它们的构造相反的顺序被调用(即 - DerivedClass 和 BaseClass )。
【参考方案1】:
好吧,如果它有一个virtual
析构函数,当然该对象将被销毁并按预期释放内存。如果它没有virtual
析构函数,则行为未定义。
如果待删除对象的静态类型与其动态类型不同,则静态类型应为待删除对象动态类型的基类,且静态类型应具有虚析构函数或行为未定义。
因此,尝试推断内存是否将被完全释放并没有任何意义。程序可以对内存做任何事情。
【讨论】:
【参考方案2】:如果析构函数不是虚拟的,delete
不会删除派生类。
我试过这个:
#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;
在 G++ 4.7.3 上编译(默认优化),我得到了
Creating base.
Creating derived.
Killing base.
注意Killing derived.
的缺失
【讨论】:
据我了解,析构函数只是在对象被程序实际销毁之前进行手动清理的一种手段。所以,如果我错了,请纠正我,但我认为这段代码证明不了。delete
both runs the destructor and frees the memory 如果内存是在堆上分配的(就像使用 new
分配内存时一样)。如果没有调用析构函数,我认为可以肯定地说内存也没有被释放。
@AnubhavC 我将您的回答进一步深入,并添加了一些应该考虑的点。如果您有兴趣:***.com/a/41801254/1971003以上是关于“删除”是不是适用于多态性? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
多态性:为啥使用“List list = new ArrayList”而不是“ArrayList list = new ArrayList”? [复制]