Инструкции, которые могут возбуждать исключения, должны быть заключены в
for ( int ix = 1; ix 51; ++ix ) {
try { // try-блок для исключений pushOnFull
if ( ix % 3 == 0 )
stack.push( ix );
}
catch ( pusOnFull ) { ... }
if ( ix % 4 == 0 )
stack.display();
try { // try-блок для исключений popOnEmpty
if ( ix % 10 == 0 ) {
int dummy;
stack.pop( dummy );
stack.display();
}
}
catch ( popOnEmpty ) { ... }
}
В таком виде программа выполняется корректно. Однако обработка исключений в ней перемежается с кодом, использующимся при нормальных обстоятельствах, а такая организация несовершенна. В конце концов, исключения – это аномальные ситуации, возникающие только в особых случаях. Желательно отделить код для обработки аномалий от кода, реализующего операции со стеком. Мы полагаем, что показанная ниже схема облегчает чтение и сопровождение программы:
try {
for ( int ix = 1; ix
С try-блоком ассоциированы два catch-предложения, которые
могут обработать исключения pushOnFull и popOnEmpty, возбуждаемые
функциями-членами push() и pop() внутри этого блока. Каждый catch-обработчик
определяет тип "своего" исключения. Код для обработки исключения помещается
внутрь составной инструкции (между фигурными скобками), которая является частью
catch-обработчика. (Подробнее catch-предложения мы рассмотрим в следующем разделе.)
Исполнение программы может пойти по одному из следующих путей:
если исключение не возбуждено, то выполняется код внутри try-блока, а ассоциированные
* с ним обработчики игнорируются. Функция main() возвращает 0;
если функция-член push(), вызванная из первой инструкции if внутри цикла for,
возбуждает исключение, то вторая и третья инструкции if игнорируются,
управление покидает цикл for и try-блок, и выполняется обработчик исключений
* типа pushOnFull;
если функция-член pop(), вызванная из третьей инструкции if внутри
цикла for, возбуждает исключение, то вызов display() игнорируется,
управление покидает цикл for и try-блок, и выполняется обработчик исключений
* типа popOnEmpty.
Когда возбуждается исключение, пропускаются все инструкции,
следующие за той, где оно было возбуждено. Исполнение программы
возобновляется в catch-обработчике этого исключения. Если такого
обработчика не существует, то управление передается в функцию terminate(),
определенную в стандартной библиотеке C++.
Try-блок может содержать любую инструкцию языка
C++: как выражения, так и объявления. Он вводит локальную
область видимости, так что объявленные внутри него переменные
недоступны вне этого блока, в том числе и в catch-обработчиках.
Например, функцию main() можно переписать так, что объявление переменной
stack окажется в try-блоке. В таком случае обращаться к этой переменной в
catch-обработчиках нельзя: