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

Спецификации исключительных ситуаций

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

объявление функции throw(тип1, тип2,…){тело функции}

где тип1, … - список типов, которые может иметь выражение throw внутри функции. Если список типов пуст, то компилятор полагает, что функцией не будет выполняться ни какой throw.

void fun(char c) throw();

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

Задание собственного неожиданного обработчика

Так же как и обработчик terminate(), обработчик unexpected() позволяет перед завершением программы выполнить какие-то действия. Но в отличие от обработчика завершения неожиданный обработчик может сам генерировать исключительные ситуации. Таким образом, собственный неожиданный обработчик может сгенерировать исключительную ситуацию, на этот раз уже входящую в спецификацию. Установка собственного неожиданного обработчика выполняется с помощью функции set_unexpected().

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

#include <iostream.h>

#include <exception>

class first{};

class second : public first{};

class third : public first{};

class my_class{};

void my_unexpected()

{ cout<<"my_unexpected handler"<<endl;

throw third(); // возбуждение исключения типа объект

} // класса third

void f(int i) throw(first) // указание спецификации исключения

{ if(i ) throw second(); //

else throw my_unexpected();

}

void main()

{ set_unexpected(my_unexpected);

try {

f(1);

}

catch(first) {

cout<<"first handler"<<endl;

}

catch(my_class) {

cout<<"my_class handler"<<endl;

}

try{

f(0);

}

catch(first) {

cout<<"first handler"<<endl;

}

catch(my_class) {

cout<<"my_class handler"<<endl;

}

}

Результат выполнения программы.

first handler

my_unexpected handler

first handler

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

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

Вершиной иерархии является класс 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) указывают на математические ошибки переполнения сверху и снизу.

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