В каком порядке будут вызваны деструкторы при удалении указателя базового класса с виртуальным деструктором, указывающего на объект производного класса?

«В каком порядке будут вызваны деструкторы при удалении указателя базового класса с виртуальным деструктором, указывающего на объект производного класса?» — вопрос из категории ООП, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

  1. Деструктор производного класса.
  2. Деструктор базового класса.

Почему это важно? Без виртуального деструктора вызовется только деструктор базового класса, что приведёт к неопределённому поведению (UB) и утечке ресурсов, выделенных в производном классе.

Пример на C++:

#include <iostream>

class Base {
public:
    virtual ~Base() { // Виртуальный деструктор
        std::cout << "Base destructor called.n";
    }
};

class Derived : public Base {
    int* dynamicArray;
public:
    Derived() : dynamicArray(new int[100]) {}
    ~Derived() override {
        delete[] dynamicArray; // Освобождение ресурсов производного класса
        std::cout << "Derived destructor called.n";
    }
};

int main() {
    Base* ptr = new Derived(); // Указатель базового типа на объект Derived
    delete ptr; // Благодаря virtual ~Base() вызовется цепочка деструкторов
    return 0;
}

Вывод программы:

Derived destructor called.
Base destructor called.

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