2010-03-19 1 views
24

Если в моем коде у меня есть следующий фрагмент кода:Бросок внутри эллипсиса ловит (...) реконструировать исходную ошибку в C++?

try { 
    doSomething(); 
} catch (...) { 
    doSomethingElse(); 
    throw; 
} 

Будет ли бросок Rethrow конкретного исключения перехватывается обработчиком многоточия по умолчанию?

ответ

31

Да. Исключение активно до тех пор, пока оно не будет поймано, когда оно станет неактивным. Но он живет до тех пор, пока объем коннектора не закончится. Из стандарта основное внимание уделяется:

§15.1/4: Память временной копии исключаемого исключения распределяется неопределенным способом, за исключением случаев, указанных в п. 3.7.4.1. Временное сохранение сохраняется до тех пор, пока выполняется обработчик для этого исключения.

То есть:

catch(...) 
{ // <-- 

    /* ... */ 

} // <-- 

Между этими стрелками, вы можете повторно бросить исключение. Только тогда, когда заканчивается область обработчиков, исключение перестает существовать.

В самом деле, в §15.1/6 в приведенном примере является почти такой же, как ваш код:

try { 
    // ... 
} 
catch (...) { // catch all exceptions 
    // respond (partially) to exception <-- ! :D 
    throw; //pass the exception to some 
      // other handler 
} 

Имейте в виду, если вы throw без активного исключения terminate будет называться. Это не может быть для вас, будучи в обработчике.


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

То есть:

void doSomethingElse(void) 
{ 
    try 
    { 
     throw "this is fine"; 
    } 
    catch(...) 
    { 
     // the previous exception dies, back to 
     // using the original exception 
    } 

    try 
    { 
     // rethrow the exception that was 
     // active when doSomethingElse was called 
     throw; 
    } 
    catch (...) 
    { 
     throw; // and let it go again 
    } 

    throw "this replaces the old exception"; 
    // this new one takes over, begins stack unwinding 
    // leaves the catch's scope, old exception is done living, 
    // and now back to normal exception stuff 
} 

try 
{ 
    throw "original exception"; 
} 
catch (...) 
{ 
    doSomethingElse(); 
    throw; // this won't actually be reached, 
     // the new exception has begun propagating 
} 

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

+0

Что делать, если doSomethingElse() выбрасывает что-то еще? Любопытная вещь. –

+0

«и обработчик был пойман в концы» звучит сбивает с толку. Нет необходимости в том, чтобы его близкая скобка была достигнута, согласно указанному вами параграфу. – Potatoswatter

+0

@jdk: вызывается 'terminate'; см. последнюю строку примера, 'throw 2;' где '2' - это новое исключение. –