Каковы различия между сгенерированным компилятором конструктором по умолчанию и определяемым пользователем конструктором по умолчанию, которые делают это возможным?
new
выражение вызывает соответствующий operator new
и затем вызывает конструктор. Если конструктор выдает исключение new
, выражение должно отменить эффект operator new
(чтобы избежать утечки памяти), вызвав соответствующий operator delete
. Если последнее удалено, new
выражение не может вызвать его, что приводит к компилятору error: use of deleted function 'static void C::operator delete(void*)'
.
Конструктор noexcept
не может вызвать исключение, следовательно, соответствующий operator delete
не является необходимым, так как он не будет вызываться выражением new
. Конструктор default
тривиального класса также является конструктором noexcept
. Присутствие виртуального деструктора требует, чтобы operator delete
был не удален, потому что специальный скалярный деструктор удаления (подробности реализации, позволяющие включить выражение delete
через указатель базового класса) вызывает operator delete
.
Стандарт C ++, похоже, не указывает, должен ли компилятор требовать, чтобы operator delete
не удалялся, даже если он не может быть вызван выражением new
. Однако gcc
, похоже, вообще не вызывает соответствующее выражение operator delete
в new
, если оно delete
d (опубликовано сообщение об ошибке ).