Программирование >>  Разработка устойчивых систем 

1 2 [ 3 ] 4 5 6 ... 196


try {

программный код. который может генерировать исключения } catch(typel idl) {

Обработка исключений типа typel } catch(type2 id2) {

Обработка исключений типа typeZ } catch(type3 ld2) {

И т. д. } catch(typeN idN)

Обработка исключений типа typeN

Здесь продолжается нормальное выполнение программы...

По своему синтаксису секции catch напоминают функции, вызываемые с одним аргументом. Идентификатор (idl, id2 и т. д.) может использоваться внутри обработчика по аналогии с аргументом функции, но если он не нужен - не используйте его. Тип исключения обычно дает достаточно информации для его обработки.

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

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

Для демонстрации работы конструкции try/catch в следующей версии файла

Nonlocal.cpp вызов setjmp() заменен блоком try, а вызов longjmpO ~ командой throw:

: C0bNonlocal2.cpp

Демонстрация обработки исключений

#include <iostream>

using namespace std:

class Rainbow { public:

RainbowO { cout RainbowO endl: } -RainbowO { cout -RainbowO endl: } }:

void ozO { Rainbow rb:

for(int i = 0: i < 3: i++)

cout theres no place like home\n : throw 47:

int mainO { try {

cout tornado, witch, munchkins...\n : ozO:

catch (int) { cout Auntie Em!

I had the strangest dream...



В языке BASIC давно поддерживается ограниченная модель обработки исключений с продолжением программы (команда ON ERROR).

При выполнении команды throw в функции oz() начинается перебор секций catch до тех пор, пока не будет обнаружена секция catch с параметром типа int. Тело этой секции catch продолжает выполнение программы. Важнейшее отличие этой версии от версии из файла Nonlocal.cpp состоит в том, что при выходе из функции oz() по команде throw вызывается деструктор объекта гЬ.

Завершение и продолжение

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

Альтернативная модель обработки ошибок впервые появилась в языке PL/I в 1960-х годах Семантика этой модели предполагает, что обработчик исключения каким-то образом исправит ситуацию, после чего сбойный фрагмент кода будет автоматически выполнен заново; причем считается, что вторая попытка может оказаться успешной. Если вы захотите организовать подобную модель поведения в С++, вам придется явно передать управление к точке возникновения ошибки (обычно посредством вызова функции). Нередко блок try помещается в цикл while и выполняется до тех пор, пока результат не окажется удовлетворительным.

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

Поиск подходящего обработчика

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

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

endl:



Более того, в обработчиках исключений практически всегда следует задавать объекты исключений по константной ссылке (модификация исключения с повторным запуском применяется редко). Тем не менее, мы не настаиваем на этом.

объект исключения усекается до базового типа при передаче обработчику. Усечение безвредно, но оно приводит к потере всей информации, специфической для производного типа.) По этой причине, а также чтобы предотвратить создание лишней копии объекта исключения, всегда лучше перехватывать исключения по ссылке, а не по значению. При запуске указателя обработчик ишется по стандартным правилам преобразования указателей. Тем не менее, в процессе поиска автоматические преобразования одного типа ис101ючения к другому типу не выполняются. Пример:

: C01:Autoexcp.cpp

Отсутствие преобразований при поиске обработчика #include <iostream> using namespace std:

class Exceptl {}:

class Except2 { public: Except2(const Exceptl&) {}

void fO { throw ExceptlO: }

int mainO { try { fO:

} catch (Except2&) {

cout inside catch(Except2) endl: } catch (Exceptl&) {

cout inside catch(Exceptl) endl:

} /:-

Хотя на первый взгляд может показаться, что первый обработчик может быть выбран в результате преобразования объекта Exceptl в ExceptZ с использованием преобразующего конструктора, при обработке исключений система не выполняет такие преобразования, и в итоге будет выбран обработчик Exceptl.

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

: C01:Basexcpt.cpp Иерархии исключений #incl ude <iostream> using namespace std:

class X { public:

class Trouble {}:

class Small : public Trouble {}:

class Big : public Trouble {}:

void fO { throw BigO: }

int mainO { X x:



1 2 [ 3 ] 4 5 6 ... 196

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика