我很难理解为什么以下代码没有按照我期望的方式构造和破坏我创建的两个对象:
#include <iostream>
class MyClass {
int myVar;
public:
MyClass(int x) {
myVar = x;
std::cout << "constructing " << myVar << ", " << (long)this << std::endl;
}
~MyClass() {
std::cout << "destructing " << myVar << ", " << (long)this << std::endl;
}
};
int main(int argc, const char * argv[])
{
MyClass a = MyClass(1);
a = MyClass(2);
return 0;
}
我认为在 main 内部我首先创建一个值为 1 的对象,然后创建一个值为 2 的新对象。每个对象都被构造和破坏,因此我希望看到以下输出:
constructing 1, 3456
constructing 2, 6789
destructing 1, 3456
destructing 2, 6789
但是,我明白了:
constructing 1, 3456
constructing 2, 6789
destructing 2, 6789 <- note the "2"
destructing 2, 3456
更新:我添加了对象地址(this)的输出,以便更好地查看哪个对象做了什么。
当我改用“new MyClass”时,我不会遇到这种奇怪的效果。
是什么导致了这种情况,并且了解我的目标,在未来避免类似错误的正确方法是什么?
虽然这个例子看起来无害,但我的代码却遇到了崩溃,因为我在构造函数中分配了其他对象并在析构函数中释放了它们。这确实导致在对象仍在使用时释放对象。
结论
现在我的所有问题都得到了解答,让我总结一下:
- 在上面的示例中,我使用的是“myVar”,它甚至没有显示导致我提出这个问题的问题。对此我深表歉意。
- 我在代码中遇到的实际问题是我没有使用简单的 int var,而是我在析构函数中使用“new”创建的数组,并在析构函数中使用 delete 释放。这样,数组将被删除两次,导致我的程序中的数据不正确。
- 解决方法是不使用指向数组的简单指针,而是使用引用计数指针,这样,当它被赋值运算符复制时,它会增加 refcount,从而防止过早释放它。
- 总的来说,我在这里展示的效果并没有什么危险——它不会损坏任何东西,就像我得到的印象一样。危险的部分是我没有使用 ref 计数 ptrs。