当我使用dynamic_cast并删除对象删除时,析构函数如何工作?

时间:2017-08-04 14:35:49

标签: c++ c++11

我为它创建了派生类的对象和基类点, 然后我使用dynamic_cast转换基类指向派生类点。    我删除派生类的点,但程序调用派生的析构函数和基础析构函数。为什么程序会调用基础析构函数?毕竟,基础析构函数不是虚函数....

#include<iostream>
#include<stdlib.h>
using namespace std;


class con {
private:
    double num;
public:
    con() {
        num = 0;
        cout << "default..." << endl;

    }
    void getnum() {
        cout << num << endl;
    }
};




class base {
public:
    virtual void A() {
        cout << "it is base A" << endl;
    }

    void B() {
        cout << "it is base B" << endl;
    }

    ~base() {
        cout << "it is base decon" << endl;
    }
};


class child : public base {
public:
    void A() {
        cout << "it is child A" << endl;
    }

    void B() {
        cout << "it is child B" << endl;
    }

    ~child() {
        cout << "it is child decon" << endl;
    }

};


int main(int argc, char** argv) {

    base* b = new child();
    child* c = dynamic_cast<child*>(b);
    delete c; //the program print "it is child decon"   "it is base decon"
    getchar();
    return 0;
}

2 个答案:

答案 0 :(得分:1)

情况1:如果删除指针派生类,它总是首先调用派生类的析构函数,然后调用基类的析构函数。

案例2:如果使用 非虚拟 基类析构函数删除指向派生类的基类的指针,则它不知道派生的class所以它只删除基类。

案例3:如果使用 虚拟 基类析构函数删除指向派生类的基类的指针,它会使用虚拟派发到派生的析构函数class,然后调用基类的析构函数。

案例2很糟糕。它可能导致资源泄漏等。应该通过始终在要作为基类的类中声明虚拟析构函数来避免它。

您的示例说明了案例1。

如果您想要查看案例2,请在示例中尝试delete b而不是delete c

答案 1 :(得分:0)

C ++中的析构函数不会超载&#34;因此;他们连锁起来。当你说

{
    child c;
}

然后在结束括号中,编译器将插入对~child()的调用,该调用将依次调用~base()(以及其他基类的析构函数,如果有的话)。这对于避免内存泄漏至关重要 - 否则base的成员将如何被销毁?请注意,这并不要求base析构函数为virtual

当您使用delete手动销毁某些内容时,此方法的工作方式相同:

child* c = new child{};

delete c; // runs ~child(), which calls ~base()

再次,这并不要求析构函数为virtual

虚拟析构函数所做的是允许您使用指向child的指针来销毁动态类型为base的变量,即

 child* c = new child{}
 base* b = c;
 delete b; // Will call ~child() if destructor is virtual, otherwise ~base()