Производные классы могут иметь собственный оператор удаления. Эта функция используется очень редко — по моему опыту, почти никогда. Виртуальный деструктор позволяет вызывать правильный оператор удаления при использовании выражения удаления (delete p
).
Компилятор определенно сгенерировал виртуальный деструктор с удалением, который вызывает специфичный для класса оператор удаления, который почти во всех случаях оказывается глобальным оператором удаления (::operator delete
), но его также можно переопределить локальным оператором, определенным в классе.
Поскольку delete
никогда не используется (для этого конкретного типа), эта автоматически сгенерированная виртуальная функция деструктора с удалением никогда не вызывается, но на нее по-прежнему ссылаются в vtable. Если у вас нет соответствующей поддержки компилятора и компоновщика, на каждую виртуальную функцию ссылаются в виртуальной таблице, а виртуальная таблица используется, по крайней мере, в конструкторах класса, поэтому любому созданному объекту потребуется каждая виртуальная функция этого класса.
Если у вас есть соответствующая поддержка компоновщика, вы можете использовать только именованные виртуальные функции; другие записи vtable могут быть нулевыми, поскольку на них никогда не ссылаются.
РЕДАКТИРОВАТЬ: стандартная цитата
Из [class.dtor]/12 :
В точке определения виртуального деструктора (включая неявное определение) функция освобождения памяти без массива определяется так же, как для выражения delete this
, появляющегося в невиртуальном деструкторе. > класса деструктора (см. [expr.delete]). Если поиск терпит неудачу или если функция освобождения имеет удаленное определение, программа неправильно сформирована. [ Примечание. Это гарантирует, что функция освобождения, соответствующая динамическому типу объекта, доступна для выражения удаления ([class.free]). — конец примечания ]
"виртуальный деструктор"... определяется так, как если бы "не виртуальный деструктор" содержал выражение — это словоблудие, которое может быть трудно расшифровать: поскольку деструктор виртуальный, почему мы говорим о виртуальном деструкторе ? (Мне пришлось прочитать приведенный выше стандартный текст несколько раз.)
Другой способ просмотра - это с точки зрения возможной реализации (некоторые реализации использовали именно это):
Каждый деструктор на самом деле принимает логический параметр deallocate
, а компилятор добавляет код:
if (deallocate)
delete this;
непосредственно перед концом тела деструктора, и все деструкторы вызываются с аргументом false
, кроме одного полного объекта, когда вызывается оператор delete
.
person
curiousguy
schedule
20.08.2017