Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
40
Добавлен:
16.02.2016
Размер:
382.98 Кб
Скачать

Операторы управления исключениями

Язык C++ позволяет программисту описывать обработку некоторых исключительных ситуаций, называемых также исключениями. Исключение -это попросту название некоторой ошибки.

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

  • оператор try указывает блок кода, для которого возможно возникновение и обработка исключений. Если при выполнении блока try не возникло ни одного исключения, то управление передается на первый оператор, следующий за блоком catch;

  • оператор throw инициирует бросок (возникновение) исключения. После этого выполнения управление передается обработчику исключений;

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

  • по завершении обработки исключения управление передается на первый оператор после всех блоков catch, следующих за найденным блоком обработки исключений;

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

Операторы, используемые для управления исключениями, могут иметь следующее формальное описание:

try_блок_кода:

try составной_оператор список_обработчиков_исключений

список_обработчиков_исключений :

обработчик_исключений список_обработчиков_исключенийoрt

обработчик_исключений :

catch ( объявлениеисключения ) составной_оператор

объявление_исключения:

type-specifier-list declarator

type-specifier-list abstract-declarator

type-specifier-list

throw_выражение :

throw выражение_присваиванияoрt

Составной_оnepamop, следующий после оператора try, определяет блок кода, для которого будет выполняться обработка исключений. Составной_оператор, следующий после оператора catch, определяет блок кода, на который будет передано управление в случае возникновения исключения. Можно определять обработчики исключений:

  • отдельно для каждого типа, включая тип класса;

  • общие для всех типов.

Для того чтобы указать, что данный блок кода является обработчиком исключений для всех типов, в операторе catch в качестве объявление_исключения следует указать символ многоточия (...).

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

Оператор throw с точки зрения синтаксиса аналогичен оператору return.

Пример:

#include <iostream.h>

int main()

{ char *buf;

Try

{ buf = new char[100];

if( buf == 0 ) throw "Ошибка выделения памяти!";

}

catch( char *str ) // Обработка исключения типа char *.

{ cout << "Выполняется блок обработки исключения:" « str « '\n';

}

return 0;

}

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

Пример:

«include <iostream.h>

void MyFunc( void );

class CTest {public:

CTest(){}; //Конструктор

~CTest(){}; //Деструктор

const char *ShowReason() const {return "Исключение для класса CTest."; }

};

class Cdemo

{public:

CDemo(); //Конструктор

~CDemo(); //Деструктор

};

CDemo::CDemo() // Описание конструктора

{ cout << "Выполнение конструктора CDtorDemo.\n";}

CDemo::CDemo() // Описание деструктора

{ cout « "Выполнение деструктора CDtorDemo.\n";}

void MyFunc()

{ CDemo D; // Создание объекта типа CDemo

cout<< "Выполняется MyFunc(). Возникновение исключения CTest.\n";

throw CTest(); // Бросок исключения

}

int mainO

{ cout « "B main.\n";

try

{ cout « "В блоке try.\n";

MyFunc();

}

catch( CTest E ) // Блок обработки исключения

{ cout << "Выполняется обработчик исключения\n";

cout « "для типа CTest:";

cout « E.ShowReason() «"\n";

}

catch( char *str)

{ cout << "Произошло исключение:" << str << "\n";

}

cout << "Возврат в main. Возобновление выполнения программы.\n";

return 0;

}

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

Пример:

try { throw MyException();

}

catch(...) // Обработчик всех исключений

{

//...

throw; // Передача исключения другому обработчику исключений

}

Обработка отсутствующих исключений

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

Для того чтобы указать собственные действия, выполняемые перед завершением программы, при вызове функции terminate следует вызвать функцию set_terminate, указав в качестве параметра имя вызываемой функции. Функция set_terminate может вызываться в любом месте программы, однако при аварийном завершении используется имя, указанное последней выполнившейся функцией.

Пример:

//...

void term_func() { // Функция, выполняемая при завершении программы }

int main()

{ try

{ set_terminate( term_func ); // Имя функции, вызываемой

// при аварийном завершении программы

throw "He хватает памяти!"; // Для этого исключения нет обработчика

}

catch( int)

{ cout << "Обработка исключений типа int."; }

return 0;

}

Операторы_try-_except и_try-_finally

Microsoft C++ поддерживает два вида операторов управления исключениями:

  • операторя языка C++ try, throw, catch;

  • операторы расширения Microsoft_try-_except,_try- finally.

Операторы _try-_except и _try-_finally обрабатываются аналогично соответствующим оператором языка C++. Однако механизм обработки исключений для операторов C++ является более гибким, так как он позволяет обрабатывать исключения в соответствии с их типом.

Операторы расширения Microsoft, используемые для управления исключениями, могут иметь следующее формальное описание:

try_except_onepaтop :

_try составной_оператор

_except ( выражение ) составной_оператор

try_finally_оператор :

_try составной_оператор

_finally составнойоператор

Соседние файлы в папке VC++Баженова