Перехват исключений
В языке C++ исключения обрабатываются в предложениях catch. Когда какая-то инструкция внутри try-блока возбуждает исключение, то просматривается список последующих предложений catch в поисках такого, который может его обработать.
Catch-обработчик состоит из трех частей: ключевого слова catch, объявления одного типа или одного объекта, заключенного в круглые скобки (оно называется объявлением исключения), и составной инструкции. Если для обработки исключения выбрано некоторое catch-предложение, то выполняется эта составная инструкция. Рассмотрим catch-обработчики исключений pushOnFull и popOnEmpty в функции main()
более подробно:
catch ( pushOnFull ) { cerr << "trying to push value on a full stack\n"; return errorCode88; } catch ( popOnEmpty ) { cerr << "trying to pop a value on an empty stack\n"; return errorCode89; |
|
}
В обоих catch-обработчиках есть объявление типа класса; в первом это pushOnFull, а во втором– popOnEmpty. Для обработки исключения выбирается тот обработчик, для которого типы в объявлении исключения и в возбужденном исключении совпадают. (В главе 19 мы увидим, что типы не обязаны совпадать точно: обработчик для базового класса подходит и для исключений с производными классами.) Например, когда функция-член pop()
класса iStack
возбуждает исключение popOnEmpty, то управление попадает во второй обработчик. После вывода сообщения об ошибке в cerr,
функция main()
возвращает код errorCode89.
А если catch-обработчики не содержат инструкции return, с какого места будет продолжено выполнение программы? После завершения обработчика выполнение возобновляется с инструкции, идущей за последним catch-обработчиком в списке. В нашем примере оно продолжается с инструкции return в функции main(). После того как catch-обработчик popOnEmpty выведет сообщение об ошибке, main()
вернет 0.
int main() { iStack stack( 32 ); try { stack.display(); for ( int x = 1; ix < 51; ++ix ) { // то же, что и раньше } } catch ( pushOnFull ) { cerr << "trying to push value on a full stack\n"; } catch ( popOnEmpty ) { cerr << "trying to pop a value on an empty stack\n"; } // исполнение продолжается отсюда return 0; |
}
Говорят, что механизм обработки исключений в C++ невозвратный: после того как исключение обработано, управление не возобновляется с того места, где оно было возбуждено. В нашем примере управление не возвращается в функцию-член pop(), возбудившую исключение.