Виртуальный деструктор

Автор: | 5 августа, 2019

Данный метод использует удаление класса потомка имея указатель на базовый класс.

Рассмотрим следующий фрагмент кода:

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() 

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