Рассмотрим следующий код:
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 #).
Кроме того, что происходит, когда я звоню удалить [] объекты? Из того, что я прочитал, только указатель фактически удален. Означает ли это, что я должен циклически проходить через каждый объект и вручную удалять его? Если сам объект также хранит другие объекты (в куче), нужно ли мне уничтожать эти объекты в его методе деструктора? (Который будет автоматически вызываться при использовании уничтожить объект).
Когда вы выполняете *(objects + i) = Object()
временный Object
экземпляр создается в стеке и передается оператору присваивания класса Object
, с this
являющийся objects+i
,
Если оператор присваивания не определен, то вызывается оператор присваивания по умолчанию.
Оператор присваивания по умолчанию просто копирует каждое из полей члена входного объекта в соответствующее поле члена this
(аналогично операции присваивания структуры).
Итак, комментарий //All objects are destroyed here!
неправильно.
Когда вы выполняете Object* objects = new Object[cnt]
массив Object
экземпляры создаются, и конструктор по умолчанию (пустой) вызывается для каждого из них.
Так что цикл, который выполняет *(objects + i) = Object()
для каждого экземпляра здесь совершенно избыточно, потому что вы по сути создаете Object
экземпляр, использующий конструктор по умолчанию (пустой), а затем передающий его оператору присваивания для каждого экземпляра в массиве.