在堆上存储实例并从指针引用它

时间:2014-05-23 18:53:57

标签: c++ pointers heap destroy

请考虑以下代码:

int cnt = 10;
Object* objects = new Object[cnt];
for(int i = 0; i < cnt; i++) {
    *(objects + i) = Object();
}
//All objects are destroyed here!

程序退出循环时,所有对象都将被销毁。我认为这是因为它们超出了范围(当我调试它时,每个对象的析构函数都被调用)。如何将它们存储在堆上但仍然从指针引用它们?为什么不允许以下内容?

*(objects + i) = new Object(); //not allowed by compiler

更新: 似乎只有临时对象被破坏了。我一直在寻找一种方法来将这些临时对象存储在堆上(这样它们不是临时的)但这会造成内存泄漏。混淆来自这样一个事实:我不知道在创建时会自动初始化一个对象数组(我来自C#)。

另外,当我调用 delete []对象时会发生什么?根据我的阅读,实际上只删除了指针。这是否意味着我必须遍历每个对象并手动删除它?如果对象本身也存储其他对象(在堆上),我是否必须在其析构函数方法中销毁这些对象? (当我使用 destroy object 时会自动调用它。)

1 个答案:

答案 0 :(得分:3)

执行*(objects + i) = Object()时,会在堆栈上创建临时Object实例并传递给类Object的赋值运算符,this为{{1} }}

如果未定义赋值运算符,则调用默认赋值运算符。

默认赋值运算符只是将输入对象的每个成员字段复制到objects+i的相应成员字段中(以类似于结构赋值操作的方式)。

因此评论this是错误的。


执行//All objects are destroyed here!时,会创建一个Object* objects = new Object[cnt]个实例数组,并为每个实例调用默认(空)构造函数。

因此,为每个实例执行Object的循环在这里是完全冗余的,因为您实际上是使用默认(空)构造函数创建*(objects + i) = Object()实例,然后将其传递给赋值运算符,对于数组中的每个实例。