Программа выведет 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.