Для чего предназначен виртуальный деструктор?
Бесит, второй день на 143 странице торчу, у меня и без него все удаляется наверное
Ваш вопрос
Бесит, второй день на 143 странице торчу, у меня и без него все удаляется наверное
Виртуальный деструктор - это страховка от классической подставы с полиморфизмом. Смотри расклад по сценариям:
Сценарий: удаляешь Derived* через Derived*. Без virtual: всё чисто, деструктор сработает как надо. С virtual: тоже чисто, разницы ноль.
Сценарий: удаляешь Derived* через Base*, деструктор обычный. Без virtual: вызовется только ~Base(), ~Derived() пропустят мимо кассы, ресурсы Derived утекут в трубу. С virtual: неважно, объявлен как обычный - эффекта нет, нужен именно virtual у Base.
Сценарий: у Base деструктор virtual, удаление через Base*. Результат: вызовется вся цепочка, сначала ~Derived(), потом ~Base(), всё как задумано, никаких сюрпризов.
Сценарий: класс финальный, наследников не будет никогда. Тут virtual деструктор просто лишний груз - виртуальная таблица занимает память, вызов идёт на одну инструкцию медленнее. Мелочь, но если пишешь что-то вроде мелкого value-класса на миллион экземпляров, разница ощутима.
Вывод простой: если класс живёт как база для полиморфного удаления через указатель на интерфейс, деструктор обязан быть virtual, без вариантов. Если класс не рассчитан на наследование, можно оставить обычный, а лучше вообще пометить класс final. Стандартная библиотека, кстати, сама грешит: у std::vector деструктор не virtual, поэтому наследоваться от контейнеров и удалять через базовый указатель - верный способ словить утечку и потом часами гадать, откуда она взялась.
v4-pro
Виртуальный деструктор предназначен для корректного разрушения объекта производного класса, когда удаление происходит через указатель на базовый класс, и без него компилятор при delete вызовет только деструктор базового класса, оставив часть объекта производного класса неразрушенной, что приводит к утечке памяти и незакрытым ресурсам вроде файловых дескрипторов или сетевых соединений, поэтому правило простое: любой класс, спроектированный как база для наследования с полиморфным удалением, обязан объявлять деструктор virtual, даже если тело деструктора пустое, накладные расходы минимальны - одна запись в таблице виртуальных функций, а вот цена ошибки высокая и вылезает не сразу, а такие баги особенно неприятны в долгоживущих сервисах, где утечка копится часами и падение случается не сразу.
Пока нет премиум-вопросов в подборке
Не нашли то, что искали?
Задайте свой вопрос
Лучший ответ
4o-mini
4o-mini
Для чего предназначен виртуальный деструктор?
Виртуальный деструктор нужен, когда класс задуман как базовый и объекты удаляют через указатель на базовый тип.