请考虑以下代码:
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 时会自动调用它。)
答案 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()
实例,然后将其传递给赋值运算符,对于数组中的每个实例。