Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы на вопросы Осадчий А.В. гр.010902.docx
Скачиваний:
9
Добавлен:
24.04.2019
Размер:
143.34 Кб
Скачать

44. Перехватывание исключений

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

В следующем примере показан обработчик с фильтрацией по типу, позволяющий перехватить определенное исключение, в данном случае исключение FileNotFoundException.

catch (FileNotFoundException e)

{

Console.WriteLine("[Data File Missing] {0}", e);

}

45. Спецификация исключений. Обработка неожидаемых исключений.

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

<тип> FuncName(<список параметров>) throw([<тип>

[, <тип> ...]])

{

<тело функции>

}

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

Однако то, какие исключения функция прямо или косвенно выбрасывает на самом деле, выясняется только во время выполнения. Компилятор не выдает никаких ошибок или предупреждений на этот счет. Если функция, снабженная спецификацией исключений, выбрасывает непредвиденное, т. е. не указанное в спецификации, исключение, вызывается функция unexpected () . По умолчанию последняя просто вызывает terminate () . Вы можете, тем не менее, указать свою собственную функцию, которая должна активироваться при появлении непредвиденных исключений, вызвав set_unexpected (). Прототип ее находится в файле except.h

typedef void (_RTLENTRY *unexpected_function)();

unexpected_function _RTLENTRY set_unexpected(unexpected_function);

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

46. «Раскручивание» стека. Иерархия исключений стандартной библиотеки

Когда функция выбрасывает исключение, то управление передается обработчику исключений. в функцию, которая еще не завершила свою работу. Это происходит потому, что поиск нужного обработчика исключений. проходит по вложенным блокам try, которые могут находится в разных функциях. В стеке хранятся адреса возврата и лок. переменные вызванных, но еще не завершивших свою работу, функций. Механизм обр. искл. реализован таким образом, что если обработчик выброшенного искл. не найден в текущей ф-ции, то все лок. объекты, принадл. этой ф-ции, уничтожаются, т.е. удаляются из стека, а затеем поиск обработчика искл. продолжается в след. ф-ции по иерархии вызовов. При удалении лок. объектов из стека для каждого из них вызывается деструктор. Такой процесс поиска нужного обр. исключений называется раскруткой стека.

Например, следующий класс инкапсулирует выделение памяти для массива целых в конструкторе и ее освобождение в деструкторе:

class PTR {

public:

PTR() { ptr = new int[ chunk ]; }

~PTR { delete[] ptr; }

private:

int *ptr;

};

Локальный объект такого типа создается в функции manip() перед вызовом mathFunc():

void manip( int parm ) {

PTR localPtr;

// ...

mathFunc( parm ); // возбуждает исключение divideByZero

// ...

}

Если mathFunc() возбуждает исключение типа divideByZero, то начинается раскрутка стека.

Иерархия исключений стандартной библиотеки

Вершиной иерархии является класс exceptioh (определенный в заголовочном файле <exception>). В этом классе содержится функция what(), переопределяемая в каждом производном классе для выдачи сообщения об ошибке.

Непосредственными производными классами от класса exception являются классы runtime_error и logic_error ( определенные в заголовочном файле <stdexcept>), имеющие по несколько производных классов.

Производными от exception также являются исключения: bad_alloc, генерируемое оператором new, bad_cast, генерируемое dynamic_cast, и bad_typeid, генерируемое оператором typeid.

Класс logic_error и производные от него классы (invalid_argument, length_error, out_of_range) указывают на логические ошибки (передача неправильного аргумента функции, выход за пределы массива или строки).

Класс runtime_error и производные от него (overflow_error и underflow_error) указывают на математические ошибки переполнения сверху и снизу.