Варианты использования виртуального деструктора

Я прочитал несколько статей, и, как говорится, основные случаи использования виртуального деструктора:

  • полученный классы могут иметь динамическое распределение данных из кучи, то есть «владеть» этим объектом данных. Итак, им нужна некоторая процедура удаления в деструкторе. Удаление через база указатель класса требует virtual объявление деструкторов во всех полученный класс до тех с динамическим распределением данных (база класс тоже этого требует)

  • этот класс имеет virtual методы. Но это неясно для меня. Просто звоню virtual методы через база указатель класса всегда приводит кполученный-реализация звонков. Единственным исключением для этого правила является этап строительства. Буквально во время this объект не является полученный типа еще, даже если позже будет. Хорошо, а как насчет фазы разрушения? Как я понял, правило в обратном порядке. Неважно, был ли деструктор некоторого класса в иерархии объявлен как virtualво время каждого деструктора this указатель используется, как если бы этот тип класса, все производные были уже уничтожены из-за virtual д-р, или не уничтожен (и это гипотетически может быть хорошо в некотором дизайне). Может быть, дело в том, почему d-r должен быть виртуальным? Vtable будет иметь записи для полученный класс и вызов virtual методы в некоторых база класс из д-р приведет к UB? Хорошо, но это правило относится только к случаю, когда этот класс вызывает некоторые virtual методы в д-р, и они имеют реализацию в полученный классы.

Мое мнение, что также может быть случай без динамического распределения данных, без виртуальных методов во всей иерархии, но все же производные деструкторы могут выполнять некоторые критические задачи после удаления (синхронизация, разблокировка и т. Д.). И нам нужен виртуальный д-р в базовом классе. Может быть, такие случаи являются результатом плохого дизайна.

Но, в любом случае, разработчик какого-либо открытого класса не может на 100% знать, будет ли производный класс использовать виртуальные методы в d-r или выделять динамические данные. Итак, я прав, что любой публичный класс, не объявленный как final, должен объявить d-r виртуальным? Только final Ключевое слово гарантирует, что любой указатель на этот класс всегда будет этого типа, и, следовательно, может быть безопасно удален не виртуально.

0

Решение

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

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

Вот ссылка на подобное обсуждение со стандартными цитатами

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]