Нужно ли явно вызывать деструктор для "простых классов POD", выделенных с помощью"placement new"?

здесь под "простым" я подразумеваю класс с не виртуальным пустым деструктором или типом POD.

типичный пример:

char buffer[SIZE];
T *p = new(buffer) T;
...
p->~T();  // <---- always ?

что произойдет, если мы не вызовем явный деструктор на p? Я не думаю, что это неопределенное поведение или утечка памяти.
Есть ли какие-либо проблемы с повторным использованием buffer ?

4 ответов


для типа стручка или класса с тривиальные деструктор: нет. Время жизни объекта закончится, когда хранилище для объекта будет освобождено или повторно использовано. Вам не нужно вызывать деструктор явно, если вы этого не хотите.

тем не менее, нет причин не делать этого. Для типа с тривиальным деструктором вызов деструктора не будет генерировать код.

Если класс "пустой" деструктор вы допускаете возможность того, что класс имеет членов или базовые классы с нетривиальными деструкторами, тогда вы можете получить неопределенное поведение, если ваша программа полагается на эти деструкторы.

обратите внимание, что деструктор, предоставленный пользователем, является нетривиальным деструктором, даже если он не является виртуальным и пустым. Несмотря на это, вам по-прежнему разрешено заканчивать срок службы объекта с таким деструктором, просто освобождая или повторно используя его хранилище при условии, что ваша программа не зависит от каких-либо побочных эффектов деструктора. (См. 3.8 [basic.жизнь] / 4 ISO / IEC 14882: 2011)


Технически говоря, предполагая, что деструктор не высвобождает никаких ресурсов, приобретенных во время строительства, это может быть не нужно.

однако, учитывая нетехнические аспекты-поддержание и эволюция кода - я бы придерживался лучшей практики - то, что было построено, должно быть уничтожено. Сценарий для рассмотрения-что, если в будущем некоторые изменения определят соответствующий код, который будет помещен в деструктор? Будешь ли ты помнить, что избегаешь разрушения? такого типа объекта?


Если ваш класс обрабатывает некоторые ресурсы (память кучи, дескрипторы, счетчики, мьютексы...) или содержит некоторые поля, которые обрабатывают ресурсы, эти ресурсы не будут освобождены, если вы явно не вызываете деструктор. В противном случае нет никаких проблем с разрушением. Вы можете рассматривать неразрушенный класс как мусор в памяти и свободно создавать новый в том же месте.


Да, вы должны вызвать деструктор явно (пожалуйста, имейте в виду побочные эффекты T, т. е. освобождение некоторой дополнительной памяти). Кроме того, вы должны быть осторожны с выравниванием памяти при использовании размещения new.

Если вы хотите, вы можете повторно использовать буферную память.

Смотрите также http://www.parashift.com/c++-часто задаваемые вопросы-лайт/dtors.сообщение: чаво-11.14