“删除”是不是适用于多态性? [复制]

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

以上是关于“删除”是不是适用于多态性? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

C ++标准是否允许复制任意多态数据结构?

多态性:为啥使用“List list = new ArrayList”而不是“ArrayList list = new ArrayList”? [复制]

为啥 AbstractFactoryUnit 具有动态而不是静态多态性?

类 C 语言中的返回类型多态性

重新梳理IT知识之java-05面向对象

C语言的多态是不是是类似于用结构指针的强制转换来实现的,具体实现方式类似于Linux万能链表???