问题描述
在C ++中,我们可以通过取消引用将类的堆分配对象分配给堆栈分配对象。看起来似乎没有问题,而且即使析构函数也可以正常工作,但按预期工作,但是编写这样的代码是好是坏?
#include <iostream>
class cls {
public:
cls(int n) : pInt{new int{n}} {
std::cout << "Constructor\n";
}
int *pInt;
~cls() {
std::cout << "Destructor\n";
delete pInt;
}
};
int main() {
cls *hObj = new cls{100};
cls sObj = *hObj;
}
解决方法
可以复制,但是请注意,编译器生成的copy-constructor将进行 shallow 复制。
这意味着指针被复制,而不是其指向的内容。这会导致 two 用完全相同的pInt
指针反对,指向完全相同的内存。而且,您只能delete
一次。
这是the rules of three,five and zero的原因。
关于该程序为何起作用的原因,是因为您没有delete hObj
。只有sObj
析构函数将运行,因此在当前显示的代码中,只有一个delete pInt
。
如果在程序终止前添加delete hObj
,则两个析构函数将delete
拥有相同的内存,并且您将具有未定义的行为(很可能会导致崩溃)。 / p>