Проблемы деструкторов при удалении через указатель базового класса

Оба delete через Base* имеют неопределённое поведение: деструктор Base не виртуальный. Наличие другой виртуальной функции не делает деструктор виртуальным автоматически.

Короткий ответ

Что ответить на собеседовании

Оба delete через Base* имеют неопределённое поведение: деструктор Base не виртуальный. Наличие другой виртуальной функции не делает деструктор виртуальным автоматически.

Подробный разбор

Ответ с пояснениями

Условие

Опишите, в чём заключается проблема, возникающая при удалении объектов через указатель базового типа (Base*). Какой результат будет при выполнении delete baseChild; и delete baseChildChild;? Объясните, почему такое поведение считается опасным.

struct Base {
    virtual void baseFunc0() {
        std::cout << "Base::baseFunc0" << std::endl;
    }
};

struct Child : Base {
    void baseFunc0() override {
        std::cout << "Child::baseFunc0" << std::endl;
    }
};

struct ChildChild : Child {
    void baseFunc0() override {
        std::cout << "ChildChild::baseFunc0" << std::endl;
    }
};

void run() {
    Base base;
    Base* baseChild = new Child;
    Base* baseChildChild = new ChildChild;

    base.baseFunc0();
    baseChild->baseFunc0();
    baseChildChild->baseFunc0();

    delete baseChild;
    delete baseChildChild;
}

Ответ

Оба delete через Base* имеют неопределённое поведение: деструктор Base не виртуальный. Наличие другой виртуальной функции не делает деструктор виртуальным автоматически.

Добавьте в Base:

virtual ~Base() = default;

Тогда при удалении ChildChild сначала разрушится производная часть, затем Child и Base. Вызовы baseFunc0 до удаления выбирают соответствующие переопределения, но для всей исходной программы с неопределённым поведением нельзя обещать полный конкретный вывод.

Это не просто риск пропустить очистку полей: правило нарушено даже у показанных пустых по данным производных классов.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее