Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Исключения






Исключения, или исключительные ситуации (exception handling) представляют собой события, возникающие внутри программы и приводящие к ненормальной ее работе или ошибкам времени исполнения.

Выброс исключения (exception throwing) представляет собой событие, приводящее к передаче управления в секцию кода, содержащую функцию-обработчик данного исключения.

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

Исключение выбрасывается в следующих случаях:

§ нет другого способа сообщить об ошибке;

§ ошибка неисправимая (например, недостаток памяти);

§ ошибка непонятна или неожиданна.

Для обработки нештатных ситуаций в язык C++ внесены следующие служебные слова –

§ try (проконтролируй, попробуй, проверь),

§ catch (лови, перехвати)

§ throw (генерировать, порождать, имитировать событие).

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

try { контролируемый участок программы }

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

1. Программа ищет подходящий обработчик исключения.

2. Если обработчик найден, то стек очищается и управление передается обработчику исключения.

3. Если обработчик не найден, вызывается функция terminate() для завершения программы.

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

catch (тип_события_1 значение_события_1) { блок обработки события_1}catch (тип_события_2 значение_события_2) { блок обработки события_2}……catch (тип_события_n значение_события_n) { блок обработки события_n}

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

Инструкция throw имеет следующую форму записи:

throw исключение;

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

Пример 1. Иллюстрация принципов и алгоритмов обработки исключений.

#include " stdafx.h"

#include < iostream>

#include < stdio.h>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])

{ cout < < " Programme start\n";

try // start of try block

{ cout < < " Vchod v block try \n";

throw 13; // error generation

cout < < " Eta linia ne poluchit upravlenie ";

}

catch (int exception)

{ cout < < " Catched error with value ";

cout < < exception < < " \n";

}

cout < < " \nEnd of programme\n";

system(" pause");

return 0;

}

Пример 2. Иллюстрация генерации исключения из функции.

#include " stdafx.h"

#include < iostream>

#include < stdio.h>

using namespace std;

void test_exception(int t)

{ cout < < " Test iskluchenia t=" < < t< < " \n";

if (! t) throw t;

}

int _tmain(int argc, _TCHAR* argv[])

{ cout < < " Programme start\n";

try // start of try block

{ cout < < " Vchod v block try \n";

test_exception(2);

test_exception(1);

test_exception(0); }

catch (int j)

{ cout < < " Error: j=" < < j; }

cout < < " \nEnd of programme\n";

system(" pause");

return 0;

}

 

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

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

 

Пример 3. Иллюстрация исключений вида catch(...)

#include " stdafx.h"

#include < iostream>

#include < stdio.h>

using namespace std;

void handle_exception(int t)

{ try

{ // Nachalo of try block

if (! t) throw t; // generation int

if (t==1) throw 2.06; // generation double

if (t==2) throw " char*"; // generation char *

}

catch(char *s) // handler char *

{ cout < < " Exception throw " < < s < < " (t=2)\n"; }

catch(double d) // handler double

{ cout < < " Exception throw " < < d < < " (t=1)\n"; }

catch(...) // handler of any exception

{ cout < < " Error in programme\n"; }

}

int _tmain(int argc, _TCHAR* argv[])

{ cout < < " Programme start\n";

cout < < " Inside of main() function\n";

handle_exception(2);

handle_exception(1);

handle_exception(0);

cout < < " End of programme\n";

system(" pause");

return 0;

}

Пример 4. Иллюстрация общих принципов обработки исключений

#include " stdafx.h"

#include < iostream>

#include < fstream>

#include < stdlib.h>

using namespace std;

int main()

{ double a, b, c, num_a = 2340.55, num_b=210.0;

char str1[80], str2[] = " Checking file";

try

{// запись данных в файл

ofstream fout(" test", ios:: out | ios:: binary);

if(! fout)

throw " Can't open file\n";

fout.write((char *) & num_a, sizeof(double));

fout.write((char *) & num_b, sizeof(double));

fout.write(str2, strlen(str2));

fout.close();

// считывание данных из файла

ifstream fin(" test", ios:: in | ios:: binary);

if (! fin)

throw " Can't open file\n";

fin.read((char *) & a, sizeof(double));

fin.read((char *) & b, sizeof(double));

fin.read(str1, sizeof(str2));

fin.close();

str1[sizeof(str2)-1]='\0';

cout < < " a= " < < a < < " \n" < < " b= " < < b < < " \n";

cout < < " str1= " < < str1 < < " \n";

if(! b)

throw " Zero devide! ";

c = a/b;

if(printf(" Result of division: %f", c) < = 0)

throw " Output error! ";

}

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

catch(char * s)

{

puts(s);

}

cout< < '\n';

system(" pause");

return 0;

}






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.