我正在学习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
答案 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 {
}
的复制构造函数。