Исключение исключений
Почему следующее не обрабатывает исключение, которое было повторно установлено? Я пробовал все комбинации, но ни один из них не показывал результат в последнем catch, поэтому я смущен!
Derived D;
try {
throw D;
} catch ( const Derived &d) {
throw;
} catch (const Base &b) {
cout << "caught!" << endl;
}
Derived D;
try {
throw D;
} catch ( const Derived d) {
throw;
} catch (const Base b) {
cout << "caught!" << endl;
}
Derived D;
try {
throw D;
} catch ( const Derived d) {
throw;
} catch (const Base &b) {
cout << "caught!" << endl;
}
Derived D;
try {
throw D;
} catch ( const Derived &d) {
throw;
} catch (const Base b) {
cout << "caught!" << endl;
}
Ответы
Ответ 1
Повторный бросок не обрабатывается одним и тем же блоком try-catch
. Он перешел в область вызова.
В [except.throw]
(формулировка 2003):
Выражение-выражение без операнда переводит обрабатываемое исключение.
и
Когда генерируется исключение, управление передается ближайшему обработчику с соответствующим типом (15.3); "ближайший" означает обработчик, для которого выполняется составной оператор, ctor-initializer или function-body ключевое слово try было недавно введено потоком управления и еще не вышло.
Ваш блок try
вышел, поэтому его обработчики не являются кандидатами. Таким образом, ни один из блоков catch
в вашем коде не может обрабатывать повторный бросок.
По общему признанию, это довольно запутанная формулировка.
Ответ 2
Исключенное исключение должно быть уловлено каким-либо другим блоком try..catch
, а не обработчиком catch того же блока try
. См. Этот пример:
using namespace std;
class Base
{
public:
virtual ~Base(){}
};
class Derived : public Base
{
};
void f()
{
try
{
throw Derived();
}
catch(Derived& ex)
{
cout<<"Caught in f\n";
throw;
}
}
int main()
{
try
{
f();
}
catch(Base& b)
{
cout<<"Caught in main\n";
}
return 0;
}
:
Пойманный в f
Пойманный в основном
Ответ 3
Это должно работать:
Derived D;
try{
try {
throw D;
} catch ( const Derived &d) {
throw;
} catch (const Base &b) {
cout << "caught!" << endl;
}
} catch (const Base &b) {
cout << "caught here!" << endl;
}
Как и все сказанное, rethrow
выведет одно и то же исключение из блока catch.