Данный метод использует удаление класса потомка имея указатель на базовый класс.
Рассмотрим следующий фрагмент кода:
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()
Виртуальный деструктор необходим при удалении объектов производного класса через указатель на базовый, то есть вызывался деструктор реального класса, а не типа класса, на который указывается ссылка.
