Какой текст выведет программа с иерархией исключений

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

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

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

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

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

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

Условие

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

# include <iostream>
# include <thread>
using namespace std;

struct GeneralException {
    virtual void print() { std::cout << "G"; }
};

struct SpecialException : public GeneralException {
    void print() override { std::cout << "S"; }
};

void f() { throw SpecialException(); }

int main() {
    try {
        f();
    }
    catch (GeneralException e) {
        std::cout << "G";
        e.print();
    }
    catch (SpecialException e) {
        std::cout << "S";
        e.print();
    }
}

Ответ

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

SpecialException публично наследует GeneralException, поэтому первый catch уже перехватывает исключение. Локальный e имеет тип GeneralException после копирования по значению: e.print() вызывает базовую реализацию и печатает G. Предварительный std::cout печатает ещё G.

Обработчики проверяются сверху вниз, поэтому более специфический нужно ставить раньше общего. Чтобы сохранить полиморфизм, перехватывают по ссылке: catch (GeneralException& e). Тогда при прежнем теле обработчика получилось бы GS. Обычно используют const-ссылку и соответствующий const-метод print.

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

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

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

Подробнее