Данный метод использует удаление класса потомка имея указатель на базовый класс.
Рассмотрим следующий фрагмент кода:
class AA { public: AA() { qDebug() << "AA()"; } ~AA() { qDebug() << "~AA()"; } }; class BB : public AA { public: BB() { qDebug() << "BB()"; } ~BB() { qDebug() << "~BB()"; } };
// Создадим статический объект int main() { BB b; return 0; }
Порядок вызова будет следующий:
AA() BB() // При завершении вызовется следующая последовательность: ~BB() ~AA()
Сначала создается базовый класс A, затем производная B. При разрушении наоборот. Сначала вызывается деструктор производного класса, который по окончанию вызывает по цепочки деструктор базового.
Попробуем теперь создать объект в динамической памяти:
int main() { AA * b = new BB; delete b; return 0; }
Порядок вызова будет следующий:
AA() BB() // При вызове delete b; вызовется следующая последовательность: ~AA()
Как видно из примера деструктор класса ~BB() не вызывается
Добавим слово virtual к деструктору ~AA()
class AA { public: AA() { qDebug() << "AA()"; } virtual ~AA() { qDebug() << "~AA()"; } };
Перезапустим программу и увидим следующий вывод:
AA() BB() // При вызове delete b; вызовется следующая последовательность: ~BB() ~AA()
Виртуальный деструктор необходим при удалении объектов производного класса через указатель на базовый, то есть вызывался деструктор реального класса, а не типа класса, на который указывается ссылка.