Рассмотрим пример работы исключительной ситуации




ОБРАБОТКА ИCKЛЮЧЕНИЙ

Цель работы — освоить приемы обработки исключений (аварийных
ситуаций) в программах на языке C++

Краткие теоретические сведения

Исключения в C++

С++ обеспечивает встроенный механизм обработки ошибок, называемый обработкой исключительных ситуаций. Благодаря обработке ис-
ключительных ситуаций можно упросить управление и реакцию на ошиб-
ки времени исполнения. Обработка исключительных ситуаций в C++ стро-
ится с помощью трех ключевых слов: try, catch, throw. Операторы про-
граммы, во время выполнения которых вы хотите обеспечить обработку
исключительных ситуации, располагаются в блоке try. Если исключитель-
ная ситуация (т.е. ошибка) имеет место внутри блока try, искусственно она
генерируется (с помощью throw), Перехватывается и обрабатывается ис-
ключительная ситуация с помощью ключевого слова catch. Любой опера-
тор, который генерирует исключительную ситуацию, должен выполниться
внутри блока try (функции, которые вызываются внутри блока try, также
могут генерировать исключительную ситуацию). Любая исключительная
ситуация должна перехватываться оператором catch, который следует не-
посредственно за блоком try, генерирующим исключительную ситуацию.

try { // блок try

}

catch (types arg1) { // блок catch

}

catch (type2 arg2) { // блок catch

}

catch (typeN argN){ // блок catch

}

Блок try должен содержать ту часть программы, в которой вы хотите
отслеживать ошибки Это могут быть как несколько операторов внутри
одной функции, так и все операторы функции main() (что естественно вы-
зывает отслеживание ошибок во всей программе).

Когда исключительная ситуация возникает, она перехватывается со-
ответствующим ей оператором catch, который ее обрабатывает. С блоком
try может быть связано более одного оператора catch. Какой конкретно оператор catch используется, зависит от типа исключительной ситуации.
То есть, если тип данных, указанных в операторе catch, соответствует типу
исключительной ситуации, то выполняется данный оператор catch. А все
другие операторы блока try пропускаются. Если исключительная ситуация
перехвачена, то аргумент arg получает ее значение. Можно перехватить
любые типы данных, включая и создаваемые вами типы.

Оператор throw должен выполняться либо внутри блока try, либо в
любой функции, которую этот блок вызывает. Здесь исключитель-
ная ситуация —
это вызываемая оператором исключительная ситуация.
Синтаксически выражение throw появляется в двух формах.

throw

throw выражение

Выражение throw устанавливает исключение. Самый внутренний
блок try, вкотором устанавливается исключение, используется для выбора
оператора catch, который обрабатывает исключение. Выражение throw без
аргумента повторно устанавливает текущее исключение. Обычно оно ис-
пользуется для дальнейшей обработки исключения вторым обработчиком,
вызываемым из первого.

Рассмотрим пример работы исключительной ситуации

int main() {

try{ throw 10; }

catch(int i) { cout << " error " «i «endl; }
return 0;

 

}

На экран выведется сообщение; error 10. Значение целого числа, вы-
данное через throw i, хранится до завершения работы обработчика с цело-
численной сигнатурой catch(tnt). Это значение доступно для использова-
ния внутри обработчика в виде аргумента.

Пример переустановки (т. е. повторной генерации) исключения выглядит следующим образом:

catch(int n) {

throw; // переустановка

}

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

В C++ блоки try могут быть вложенными. Если в текущем блоке try
нет соответствующего обработчика, выбирается обработчик из ближайше-
го внешнего блока try. Если он не обнаружен и там, тогда используется
поведение по умолчанию.

catch выглядит подобно объявлению функции с одним параметром
без возвращаемого типа:

catch (char *message) { cerr << message << endl; exit(1);
}

catch (...) { // действие, которое нужно принять по умолчанию.

cerr << " That's all folks"<< endl; abort();

}

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

Синтаксически Спецификация исключении представляет собой
части объявления функции и имеет форму:

заголовок_функции throw (список типов)

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

void foo() throw(int, over flow);

void index(int i) throw();

Если спецификация исключения оставлена, тогда возникает допуще-
ние, что такой функцией может бьпъ установлено произвольное исключе-
ние. Хорошей практикой программирования будет показать с помощью
спецификации,какие ожидаются исключения.

Пример кода, реализующего исключения при конструировании
объекта

vect::veсt (int n) {

if (n <1) throw (n);

p=new int [n];

if(p==NULL) throw("NO MEMORY");

}

void g(int m) {

try { vect a (m); }

catch (int n) {

cerr << "SIZE ERROR" << n << endl;

g(10); // повторить g с допустимым разме-
рjм

}

catch(const char *error) { cerr << error <<
end1; abort(); }

}

где cerr - стандартный поток вывода ошибок.

Обработчик заменил запрещенное значение допустимым значением
по умолчанию. Это может быть приемлемо на этапе отладки системы, ко-
гда большинство подпрограмм объединяются и проверяются. Система пы-
тается продолжать обеспечивать дальнейшую диагностику. Это аналогич-
но компилятору, пытающемуся продолжать анализировать неправильную
программу после синтаксической ошибки. Часто компилятор предоставляет
дополнительные сообщения об ошибках, которые оказываются полезными.

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

object::object(аргументы) {

if{недопустимый аргумент 1) throw выражение 1;


if(недопустимый аргумент 2) throw выражение 2;

.... // попытка создания

}

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

try { // oтказоустайчивый код)

catch(объявление 1) { /* восстановление этого случая */ }

 

catch(объявление 2) { /* восстановление этого случая */ }

catch(объявление K) { /* восстановление этого случая */ }

 

// правильные/восстановленные переменные состояния допустимы

Когда существует много определенных ошибочных условий, удоб-
ных для состояния данного объекта, может быть использована иерархия
классов исключений. Эта иерархия позволяет соответственно упорядочен-
ному множеству catch обрабатывать исключения в логической последова-
тельности. Тип базового класса в списке catch должен следовать после ти-
па порожденного.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-12-18 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: