在 C++ 中将堆分配 class 对象分配给堆栈分配对象是否合法?
Is it legal to assign heap allocated class object to stack allocated object in C++?
在 C++ 中,我们可以通过取消引用将 class 的堆分配对象分配给堆栈分配的对象。看起来没有问题,即使析构函数也能正常工作,它也能正常工作,但是这样写代码是好是坏?
#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;
}
他们复制没问题,但请注意 compiler-generated copy-constructor 会进行 shallow 复制。
这意味着,指针 被复制,而不是它指向的内容。这导致您 two 使用完全相同的 pInt
指针对象,指向完全相同的内存。而且你只能delete
那段记忆一次。
这就是the rules of three, five and zero的原因。
至于为什么这个程序看起来有效,那是因为你没有delete hObj
。只有 sObj
析构函数会 运行,因此在当前显示的代码中只有一个 delete pInt
.
如果你在程序终止之前添加 delete hObj
,那么两个析构函数将 delete
相同的内存,你将有 未定义的行为(而且很可能崩溃)。
在 C++ 中,我们可以通过取消引用将 class 的堆分配对象分配给堆栈分配的对象。看起来没有问题,即使析构函数也能正常工作,它也能正常工作,但是这样写代码是好是坏?
#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;
}
他们复制没问题,但请注意 compiler-generated copy-constructor 会进行 shallow 复制。
这意味着,指针 被复制,而不是它指向的内容。这导致您 two 使用完全相同的 pInt
指针对象,指向完全相同的内存。而且你只能delete
那段记忆一次。
这就是the rules of three, five and zero的原因。
至于为什么这个程序看起来有效,那是因为你没有delete hObj
。只有 sObj
析构函数会 运行,因此在当前显示的代码中只有一个 delete pInt
.
如果你在程序终止之前添加 delete hObj
,那么两个析构函数将 delete
相同的内存,你将有 未定义的行为(而且很可能崩溃)。