Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP.doc
Скачиваний:
6
Добавлен:
25.04.2019
Размер:
1.34 Mб
Скачать

7. Механизм исключений

Исключения (исключительные ситуации) – это особые состояния вычислительного процесса, которые требуют специальной обработки. Они могут быть связаны с внутренними ошибками программы или с условиями (не обязательно ошибочными), которые искусственно формируются по указанию программиста. Отличие исключительных ситуаций от просто ошибок состоит в том, что в момент их возникновения нормальное выполнение программы прекращается и управление немедленно передается в ближайший по вложенности участок, который реализует их обработку, независимо от контекста, где возникло исключение. Если обработка исключения не выполняется, то происходит принудительное завершение программы. Механизм исключений в С++ достаточно тесно связан с объектным подходом и поэтому рассматривается как подраздел в рамках объектно-ориентированного программирования на С++.

7.1. Модель исключений в С++. Синтаксис и семантика обработки исключений

Для реализации обработки исключений С++ содержит три служебных слова: try, catch, throw. Служебное слово try позволяет выделить в любом месте программы контролируемый участок (блок), т.е. блок, где потенциально возможно возникновение исключительных ситуаций. Синтаксис его применения следующий:

try { statements }

После возникновения исключения в контролируемом блоке управление немедленно передается за его пределы, где должны быть размещены обработчики исключений. Каждый обработчик идентифицируется служебным словом catch и записывается в следующем формате:

catch ( declaration ) { statements }

где declaration определяет тип исключений, обрабатываемых данным обработчиком; в фигурных скобках записаны операторы блока обработки исключения.

Пример

try { // контролируемый блок

DataObject.AllocateMemory();

InputStream >> DataObject;

DataObject.Process();

OutputStream << DataObject;

}

catch(const char * e) // обработчик исключений типа const char *

{ /* ... */ }

В общем случае в контролируемом блоке могут формироваться исключения разных типов и, скорее всего, необходимо предусмотреть обработчик на каждый из них:

try { statements }

catch(declaration) // обработчик 1

{ statements }

catch(declaration) // обработчик 2

{ statements }

...

catch(declaration) // обработчик N

{ statements }

При возникновении исключения его тип последовательно сравнивается с типами, записанными в заголовках catch (осуществляется «сканирование» обработчиков); при обнаружении подходящего типа управление передается в соответствующий блок catch (а последующие обработчики пропускаются). Вместе с типом исключения в заголовке catch может быть задано и его имя; в этом случае контролируемый блок получает доступ к информации об исключении (эта информация может, например, указывать причину возникновения исключения).

В заголовке оператора catch может также ставиться символ «…». Обработчик с таким заголовком (называемый обобщенным) предназначен для обработки исключений любого типа и должен всегда ставиться последним в цепочке обработчиков. При попытке поставить обобщенный обработчик в середину или в начало цепочки обработчиков возникает ошибка компиляции или, по крайней мере, предупреждение.

Пример

try { // контролируемый блок

DataObject.AllocateMemory();

InputStream >> DataObject;

DataObject.Process();

OutputStream << DataObject;

}

catch(CIException &) // обработчик исключений класса CIException

{ statements }

catch(CIOException &) // обработчик исключений CIOException

{ statements }

catch(...) // обработчик остальных исключений

{ statements }

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

В процессе поиска обработчика учитываются: константность исключения, наличие или отсутствие ссылки, возможность автоматического приведения к типу исключения обработчика. При отсутствии подходящего обработчика в ответ на исключение вызывается библиотечная функция terminate(), которая принудительно завершает программу (о работе с ней будет рассказано далее).

Хотя тип исключения может быть одним из встроенных типов, например, int или double (или const char *, что показано в одном из примеров выше), на практике гораздо чаще исключения представляются объектами классов исключений. Использование объектов более рационально, так как позволяет обработчику получить подробную информацию о причине исключения. Кроме того, объект-исключение может использовать функциональность стандартных классов исключений (краткая информация о них имеется ниже).

Исключительная ситуация в контролируемом блоке может порождаться по указанию программиста (либо непосредственно в проекте, либо в библиотеке). При этом она не обязательно должна быть связана с каким-то аномальным поведением программы. Для формирования исключений используется оператор throw. Формат этого оператора следующий:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]