析构函数在哪里调用?

时间:2017-09-12 04:34:40

标签: c++ class pointers destructor

我正在学习C ++并希望在课堂上使用对象。我的程序输出让我感到困惑,因为我预料到数据析构函数会被调用两次。我的对象是用"数据数据(3)创建的;"并且应该在代码块的末尾调用它的析构函数,并且当调用rects析构函数时,也应该调用rect中数据的析构函数。正如我所料,它打印了数据析构函数"代码块结束后两次。但在创建数据对象后,它也会打印它。为什么会发生这种情况?如何正确删除数据内部分配的内存?

class Data {
private:
    int* data;
    int size;
public:
    Data() {
        size = 10;
        data = new int[size];
    }
    Data(int size)
        : size(size) {
        data = new int[size];
    }
    virtual ~Data() {
        // delete data;
        std::cout << "data destruktor" << std::endl;
    }
    void init(int val) {
        for (int i = 0; i < size; i++)
            data[i] = val;
    }
    int& operator[](int index) {
        return data[index];
    }
    int getSize() const {
        return size;
    }
};

class Rect {
private:
    Data data;
    int width, height;
public:
    Rect() {}
    Rect(int width, int height, Data data, int val = 0)
        : width(width), height(height), data(data) {
        data.init(val);
    }
    int getWidth() const {
        return width;
    }
    int getHeight() const {
        return height;
    }
    int getArea() const {
        return width * height;
    }
    Data& getData() {
        return data;
    }
};

int main() {

    {
        Data data(3);
        std::cout << "data created" << std::endl;
        Rect rect(5, 4, data, 9);
        std::cout << "end of code block" << std::endl;
    }

    std::cout << "end of program" << std::endl;

    system("pause");
    return 0;
}

输出:

data created
data destruktor
end of code block
data destruktor
data destruktor
end of program

2 个答案:

答案 0 :(得分:0)

那是因为你传递了Rect的c'tor一个Data的副本,它在构造函数调用之后被销毁,因此是你的析构函数调用。

答案 1 :(得分:0)

Rect(int width, int height, Data data, int val = 0)

您在此处按值传递Data,因此在调用此方法时会创建并销毁新的值。它应该是:

Rect(int width, int height, Data &data, int val = 0)

甚至可能const Data &data:当Data已经拥有自己的Rect时,不清楚为什么要传递Rect(int width, int height, const Data &data, int val = 0) : data(data) // ... 。也许你应该复制分配它,或者复制它:

delete data;

注意您确实需要delete[] data;行,实际上需要@ {P0W指出Data::Data(const Data&)。还有@Configuration @ComponentScan(basePackages = {"com.xx.xx"}) public class AppConfig { } 的复制构造函数。