То есть я могу просто трактовать деструктор как "просто функцию"?
Нет. Хотя он во многом похож на другие функции, у деструктора есть свои особенности. Они сводятся к шаблону, похожему на ручное управление памятью. Так же, как распределение и освобождение памяти должно происходить парами, так и строительство и разрушение. Если вы пропустите один, пропустите другой. Если вы звоните одному, звоните другому. Если вы настаиваете на ручном управлении памятью, инструментами для построения и уничтожения являются размещение нового и явный вызов деструктора. (Код, использующий new
и delete
, объединяет выделение и построение в один шаг, а уничтожение и освобождение объединяются в другой.)
Не пропускайте конструктор для объекта, который будет использоваться. Это неопределенное поведение. Кроме того, чем менее тривиален конструктор, тем больше вероятность, что что-то пойдет не так, если вы пропустите это. То есть, чем больше вы экономите, тем больше ломаетесь. Пропуск конструктора для используемого объекта не является способом повышения эффективности & mdash; это способ написания неработающего кода. Неэффективный, правильный код превосходит эффективный код, который не работает.
Один кусочек разочарования: такого рода низкоуровневое управление может стать большим вложением времени. Пройдите этот путь только в том случае, если есть реальная вероятность окупаемости. Не усложняйте свой код оптимизацией просто ради оптимизации. Также рассмотрите более простые альтернативы, которые могут получить аналогичные результаты с меньшими накладными расходами кода. Возможно, конструктор, который не выполняет никаких инициализаций, кроме как пометить объект как не инициализированный? (Детали и возможности зависят от участвующего класса, поэтому выходят за рамки этого вопроса.)
Один кусочек ободрения: Если вы думаете о стандартной библиотеке, вы должны понимать, что ваша цель достижима. Я бы представил vector::reserve
в качестве примера чего-то, что может выделить память без ее инициализации.