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

5.4. Иерархия исключений

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

Например:

  • ошибки распределения памяти;

  • ошибки ввода-вывода;

  • ошибки при работе с файлами;

  • ошибки при выполнении арифметических операций.

Если проанализировать все группы, то можно построить некоторую иерархию исключений с использованием принципов наследования. Можно рассмотреть базовый класс и производные классы, каждый из которых соответствует либо некоторой группе исключений, либо конкретному исключению. В качестве главного базового класса рассматривают некоторый пустой класс. Это позволяет построить иерархическую структуру с единым корнем. Тогда блоки try и catch будут иметь такой вид:

try{…}

catch(group_N)

{

//Обработка конкретного исключения нижнего уровня N

}

catch(group_N-1)

{

//Обработка исключений следующего уровня (класс group_N-1

// является базовым для класса group_N

}

catch(…)

{

//Обработка всех возможных исключений

}

Здесь в выражении catch(…) три точки означают “любой аргумент”. Поэтому обработчик catch(…) перехватывает любое исключение. Последовательность, в которой записаны различные обработчики исключений, является существенной, поскольку производные исключения могут быть перехвачены несколькими обработчиками.

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

try{…}

catch(класс-индикатор)

{if(знает как обработать исключение){обработка исключения}

else throw;

}

5.5. Спецификация функций, обрабатывающих исключения

Если некоторая функция содержит инструкцию throw для генерации исключения, то ее можно специфицировать (объявить) как функцию, генерирующую исключения, например:

void f(void) throw(x,y,z);

Здесь объявляется функция f, генерирующая исключения z, y, z и исключения, которые являются производными от x, y, z. Другие исключения функция не генерирует. В этом случае при возникновении исключений из указанного списка функция f должна установить индикатор для соответствующего обработчика. Если же возникает другое исключение, то f должна завершить свое выполнение некоторым выходом по критической (неисправимой) ошибке (например, с помощью библиотечной функции abort).

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

void f(void) – эта функция может генерировать любое исключение.

int f(void) throw() – эта функция не генерирует исключения.

Рассмотрим некоторую функцию

void f(void) throw(A);

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

По умолчанию функция unexpected вызывает другую библиотечную функцию terminate()

По умолчанию terminate вызывает функцию abort(), которая выдает сообщение

Abnormal program termination

и завершает программу. Пользователь может заменить функцию unexpected и terminate своими. Для этого надо

1) описать новую версию этой функции

void my_unexpected(void){описание новых действий}

void my_terminate(void){описание новых действий}

2) установить (зарегистрировать) новую функцию с помощью функций set_unexpected() и set_terminate();

Функция terminate() будет вызвана автоматически и тогда, когда генерируется исключение и не находится соответствующий обработчик.