2009-02-16 2 views
13

Могу ли я иметь вложенные блоки try-catch? Например:Могу ли я иметь вложенные блоки try-catch в C++?


void f() 
{ 
    try 
    { 
     //Some code 
     try 
     { 
      //Some code 
     } 
     catch(ExceptionA a) 
     { 
      //Some specific exception handling 
     } 
     //Some code 
    } 
    catch(...) 
    { 
     //Some exception handling 
    } 
}//f 
+3

Вы просто должны любить этих людей, которые думают, что они умнее всех, и считают, что они владеют этим сайтом. –

+2

Я обычно даю этим типам вопросы преимущества сомнений: только потому, что он работает на вашем компиляторе, это не значит, что это часть стандарта. Обратное также верно. – rmeador

+2

@shoosh этот вопрос спас меня хотя бы на 90 секунд от его поиска! –

ответ

19

Да совершенно законно.

Хотя было бы лучше, чтобы переместить внутренние, в другой метод, так это выглядит чище и ваш метод (ы) меньше

7

Как уже говорилось, это возможно, но вы должны увидеть «осень-через '-схема в этом. Если в первом блоке try-catch блокируется ваше исключение, он не будет попадать во внешний блокирующий блок. Однако, если он не попадает во внутренний блокирующий блок, он попытается найти соответствующий обработчик исключений во внешнем блоке catch.

Вы также можете явно добавить исключение к следующему обработчику исключений, используя throw; в своем внутреннем обработчике исключений.

Например, этот код:

try 
{ 
    try 
    { 
     throw std::runtime_error("Test"); 
    } 
    catch (std::runtime_error& e) 
    { 
     std::cerr << "Inner Exception-Handler: " << e.what() << std::endl; 
     throw; 
    } 
} 
catch (std::exception& e) 
{ 
    std::cerr << "Outer Exception-Handler: " << e.what() << std::endl; 
}

будет приводить:

Inner Exception-Handler: Test 
Outer Exception-Handler: Test

Это работает, потому что std::runtime_error is derived from std::exception. Вы также должны заметить, что в таком тривиальном примере также можно просто написать блоки catch после друг друга, но если вы хотите выполнить другой код после первого блока catch, вам придется их вложить.

1

Его правовой, но его не все, что полезно, если вы не выбрасываете исключение из своего внутреннего улова(). Например, вы можете поймать исключение на системном уровне, но бросить свой собственный объект исключения для ясности кода.

+3

Полезно, если внешний catch обрабатывает другой набор исключений – MSalters

5

Да, это законно. Как сказал ouster, одним из способов борьбы с ним является помещение внутреннего блока try-catch в его собственную функцию и вызов этой функции из вашего внешнего блока try-catch.

Другим способом обработки является использование нескольких блоков блокировки.

void f() 
{ 
    try 
    { 
     //Some code that throws ExceptionA 
     //Some code that throws ExceptionB 
    } 
    catch(ExceptionA ea) 
    { 
     //Some exception handling 
    } 
    catch(ExceptionB eb) 
    { 
     //Some exception handling 
    } 
}//f 

Вещь, которая должна быть осторожна здесь, является спецификой типов исключений в ваших блоках catch. Если ExceptionB расширяет ExceptionA в приведенном выше примере, тогда блок ExceptionB никогда не будет вызван, потому что любой ExceptionB, который будет выброшен, будет обработан блоком ExceptionA. Вы должны заказать блоки catch наиболее специфично для наименее определенного порядка при работе с иерархиями классов исключений.

Смежные вопросы