在C ++中将堆分配的类对象分配给堆栈分配的对象合法吗?

问题描述

在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>