Будет напечатано 1. primary_exception наследуется от std::exception, поэтому подходит первый catch; обработчики проверяются по порядку, а не по наибольшей специфичности.
Что выведет программа с несколькими блоками catch
Будет напечатано 1. primary_exception наследуется от std::exception, поэтому подходит первый catch; обработчики проверяются по порядку, а не по наибольшей специфичности.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Нужно предсказать, какой набор символов появится в стандартном выводе после выполнения следующей программы.
#include <iostream>
using namespace std;
struct boom_exception : public std::exception {};
struct primary_exception : public std::exception {};
struct Explosive
{
~Explosive()
{
// деструктор ничего не делает
}
};
int main()
{
try
{
Explosive explosiveObj;
throw primary_exception();
}
catch (const std::exception&)
{
cout << "1";
// обработчик 1
}
catch (primary_exception&)
{
cout << "2";
// обработчик 2
}
catch (boom_exception&)
{
cout << "3";
// обработчик 3
}
catch (int&)
{
cout << "4";
// обработчик 4
}
return 0;
}
Ответ
Будет напечатано 1. primary_exception наследуется от std::exception, поэтому подходит первый catch; обработчики проверяются по порядку, а не по наибольшей специфичности.
Деструктор Explosive не бросает исключений и нормально выполняется при раскрутке стека. Затем управление передаётся первому подходящему обработчику; остальные catch после него не выполняются.
Чтобы отдельно обрабатывать primary_exception, переместите соответствующий catch выше catch для std::exception. Производные обработчики после базового могут вызвать предупреждение компилятора, но ожидать, что автоматически выберется более точный catch, нельзя.