#cpp
Зачем в интерфейсе нужен виртуальный деструктор?
Ответы
Ответ 1
Начнём с того, что в C++ нет интерфейсов. Но часто интерфейсом называют абстрактный класс, поэтому не будем особо придираться. Для чего же в базовом классе нам нужен виртуальный деструктор? Рассмотрим следующие классы: class A { public : ~A() { } } class B : public A { private : char* buffer; public : B() : buffer(new char[1024]) { } ~B() { delete[] buffer; } } А теперь сделаем следующее: A* a = new B; // ... delete a; В этом коде память, выделенная для buffer освобождена не будет! При удалении переменной a будет вызван метод A::~A, который не производит очистку памяти, выделенной в классе B. Чтобы избежать подобного рода ошибок, деструктор базового класса объявляют виртуальным. Тогда при разрушении экземпляра класса будет вызван "правильный" деструктор. А поскольку virtual наследуется, то достаточно объявить деструктор виртуальным только у базового класса, во всех дочерних он будет виртуальным автоматически. То есть, наш базовый класс A должен быть таким: class A { public : virtual ~A() { } } Как верно заметил @alexolut в комментариях к соседнему ответу, всё ещё хуже. Согласно стандарту C++ (5.3.5.3), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. Перевод: Если статический тип удаляемого объекта отличается от его динамического типа, статический тип должен являться базовым классом динамического типа удаляемого объекта и статический тип должен иметь виртуальный деструктор, в противном случае поведение неопределено.Ответ 2
Потому что в Си++ нет интерфейсов. Указатель на наследника может быть приведён к указателю на "интерфейс". delete указателя вызовет деструктор того типа, с которым объявлен указатель. Если этот деструктор виртуальный, то вызовется деструктор типа, созданного через new. Если деструктор не виртуальный, то ты потеряешь очистку всего, что принадлежит наследнику, но не принадлежит предку. Точнее, формально, это приведёт к неопределённому поведению.
Комментариев нет:
Отправить комментарий