Назад к вопросам
Middle
86
questionbank

В каких случаях необходимо объявлять деструктор виртуальным?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Когда базовый класс используется для создания полиморфной иерархии классов (то есть, есть производные классы, и они могут быть доступны через указатель или ссылку на базовый класс), и при этом предполагается удаление объектов производных классов через указатель на базовый класс. Без виртуального деструктора вызов delete через указатель на базовый класс приведет к вызову деструктора только базового класса, что может вызвать утечки памяти или некорректное поведение, так как деструкторы производных классов не будут вызваны.

class Base {
public:
    virtual ~Base() { // Виртуальный деструктор
        // Очистка базового класса
    }
};

class Derived : public Base {
public:
    ~Derived() override { // Переопределение деструктора
        // Очистка производного класса
    }
};

int main() {
    Base* obj = new Derived();
    delete obj; // Корректно вызывает ~Derived(), затем ~Base()
    return 0;
}

Если деструктор базового класса не объявлен как virtual, и объект производного класса удаляется через указатель на базовый класс, происходит неопределенное поведение (Undefined Behavior).

class BaseNonVirtual {
public:
    ~BaseNonVirtual() { // Невиртуальный деструктор
        // Очистка базового класса
    }
};

class DerivedNonVirtual : public BaseNonVirtual {
public:
    ~DerivedNonVirtual() { // Не переопределяет виртуальный деструктор
        // Очистка производного класса
    }
};

int main() {
    BaseNonVirtual* obj = new DerivedNonVirtual();
    delete obj; // Вызывает только ~BaseNonVirtual(), ~DerivedNonVirtual() не вызывается (UB)
    return 0;
}

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