删除另一个类中的一个类的对象时析构函数的功能

时间:2019-07-16 07:12:00

标签: c++ destructor delete-operator

在下面的代码中,删除destruct类中的基类对象时,没有任何类的析构函数被执行。这可能是什么原因? “删除obj”调用的是哪个析构函数?

#include <iostream>
using namespace std;
class base;

class destruct{
    public :
    destruct() {
        cout<<"Destruct Constructor called"<<endl;
    }

    void destructObj(base* obj) {
        delete obj;
    }

    ~destruct() {
        cout<<"Destruct Destructor called"<<endl;
    }
};

class base {
    int runs;
    public:

    base(){

        cout<<"Constructor called"<<endl;
    }

    ~base(){
        cout<<"destructor called"<<endl;
    }
};

int main() {
    base *obj = new base();
    destruct *desObj = new destruct();
    desObj->destructObj(obj);
    return 0;
}

我希望至少有一个运行任何类的析构函数。 请帮助我找出在这种情况下删除运算符的工作方式。

2 个答案:

答案 0 :(得分:2)

问题是destruct::destructObj需要了解Base的定义才能知道有一个析构函数要调用,但是它所具有的只是一个前向声明。

将您的代码更改为此即可。

#include <iostream>
using namespace std;
class base;

class destruct{
    public :
    destruct() {
        cout<<"Destruct Constructor called"<<endl;
    }

    void destructObj(base* obj);

    ~destruct() {
        cout<<"Destruct Destructor called"<<endl;
    }
};

class base {
    int runs;
    public:

    base(){

        cout<<"Constructor called"<<endl;
    }

    ~base(){
        cout<<"destructor called"<<endl;
    }
};

// *** this function after base has been defined ***
inline void destruct::destructObj(base* obj) {
    delete obj;
}

int main() {
    base *obj = new base();
    destruct *desObj = new destruct();
    desObj->destructObj(obj);
    return 0;
}

现在这让我感到惊讶,我想知道它是否是g ++扩展。当您尝试delete指向仅具有前向声明的类的指针时,会发生编译器错误。但是我可能错了。

更新:显然,这(删除指向不完整类的指针)是未定义的行为,我想这暗示它应该编译。但是,您的编译器确实应该向您发出警告,告诉您存在问题。始终注意编译器警告,并始终在启用警告的情况下进行编译。

答案 1 :(得分:1)

delete obj是指向不完整类型的指针时,您正在调用obj。这是未定义的行为(在实践中,通常通常表示不调用析构函数,但是可能发生任何事情)。

您需要将base的定义上移到调用delete的函数可见的地方。