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

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

.doc
Скачиваний:
48
Добавлен:
05.06.2015
Размер:
60.93 Кб
Скачать

Дополнительное задание

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

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

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

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

Обработка исключений в С++ использует три ключевых слова: try, catch и throw. Те инструкции программы, где ожидается возможность появления исключительных ситуаций, содержится в блоке try. Если в блоке try возникает исключение, т.е. ошибка, то генерируется исключение. Исключение перехватывается, используя catch, и обрабатывается. Ниже это общее описание будет рассмотрено более подробно.

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

try {

// блок try

}

catch (тип1 аргумент) {

// блок catch

}

catch (тип2 аргумент) {

// блок catch

}

catch (типN аргумент) {

// блок catch

}

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

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

Общая форма записи инструкции throw имеет вид:

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

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

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

Пример

// обработка простого исключения

#include <iostream>

using namespace std;

int main()

{

cout << "Start\n";

try { // начало блока try

cout << "Inside try block\n";

throw 100; // генерация исключения

cout << "This will no execute";

}

catch (int i) { // перехват ошибки

cout << "Caught an exception -- value is: ";

cout << i << "\n";

}

cout << "End";

getchar();

return 0;

}

Программа выведет на экран:

Start

Inside try block

Caught an exeption – value is: 100

End

Блок try содержит три инструкции. За ним следует инструкция catch(int i), обрабатывающая исключения целого типа. В блоке try будут выполняться только две инструкции: первая и вторая – throw. Как только исключение было сгенерировано, управление передаётся инструкции catch, а блок try прекращает своё исполнение. Таким образом, инструкция после инструкции throw никогда не выполняется.

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

Как отмечалось выше, тип исключения должен соответствовать указанному в инструкции типу.

Пример

// данный пример не будет работать

#include <iostream>

using namespace std;

int main()

{

cout << "Start\n";

try { // начало блока try

cout << "Inside try block\n";

throw 100; // генерация исключения

cout << "This will no execute";

}

catch (double i) { // не будет работать для int

cout << "Caught an exception -- value is: ";

cout << i << "\n";

}

cout << "End";

getchar();

return 0;

}

Эта программа выдаст следующий результат:

Start

Inside try block

в отдельном окне, в зависимости от способа запуска

Unhandled exception at …in try.exe: MicrosoftC++ exception:

int at memory location …

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

#include <iostream>

using namespace std;

void Xtest(int test)

{

cout << "Inside Xtest, test is: " << test << "\n";

if (test) throw test;

}

int main()

{

cout << "Start\n";

try {// начало блока try

cout << "Inside try blok\n";

Xtest(0);

Xtest(1);

Xtest(2);

}

catch (int i) {// перехват ошибки

cout << "Caught an exception -- value is: ";

cout << i << "\n";

}

cout << "End";

getchar();

return 0;

}

Эта программа выдаст следующий результат:

Start

Inside try block

Inside Xtest, test is: 0

Inside Xtest, test is: 1

Caught an exception – value is: 1

End

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

Пример

#include <iostream>

using namespace std;

void Xhandler(int test)

{

try {

if (test) throw test;

}

catch (int i) {

cout << "Caught exception #: " << i << "\n";

}

}

int main()

{

cout << "Start\n";

Xhandler(1);

Xhandler(2);

Xhandler(0);

Xhandler(3);

cout << "End";

getchar();

return 0;

}

Эта программа выдаст на экран следующий текст

Start

Caught exception #: 1

Caught exception #: 2

Caught exception #: 3

End

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

Использование нескольких инструкций catch

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

Пример

#include <iostream>

using namespace std;

void Xhandler(int test)

{

try {

if (test) throw test;

else throw "Value is zero";

}

catch (int i) {

cout << "Caught exception #: " << i << "\n";

}

catch (char *str) {

cout << "Caught a string: ";

cout << str << "\n";

}

}

int main()

{

cout << "Start\n";

Xhandler(1);

Xhandler(2);

Xhandler(0);

Xhandler(3);

cout << "End";

getchar();

return 0;

}

Эта программа выдаст следующий результат на экран:

Start

Caught exception #: 1

Caught exception #: 2

Caught a string: Value is zero

Caught exception #: 3

End

Каждая инструкция catch отвечает только на свой тип исключений.

Опции обработки исключений

Перехват всех исключений

В определённых обстоятельствах может потребоваться перехватывать все исключения. Для этого достаточно использовать следующую форму инструкции catch:

catch (…) {

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

}

Следующая программа иллюстрирует использование catch (…):

#include <iostream>

using namespace std;

void Xhandler(int test)

{

try {

if (test == 0) throw test;

if (test == 1) throw 'a';

if (test == 2) throw 123.23;

}

catch (...) {

cout << "Caught One!\n";

}

}

int main()

{

cout << "Start\n";

Xhandler(1);

Xhandler(2);

Xhandler(0);

cout << "End";

getchar();

return 0;

}

Программа выведет на экран следующий текст:

Start

Caught One!

Caught One!

Caught One!

End

Повторная генерация исключений

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

Пример

#include <iostream>

using namespace std;

void Xhandler()

{

try {

throw "hello";

}

catch (char *) {

cout << "Caught char * inside Xhandler\n";

throw ;

}

}

int main()

{

cout << "Start\n";

try {

Xhandler();

}

catch (char *) {

cout << "Caught char * inside main\n";

}

cout << "End";

getchar();

return 0;

}

Эта программа выдаст на экран

Start

Caught char * inside Xhandler

Caught char * inside main

End

Варианты заданий

Номер

варианта

Задание

1, 5, 9, 13, 17, 21, 25, 29

Описать функцию деления чисел типа double. Запрограммировать генерацию исключения в случае делителя равного нулю, выдачу соответствующего сообщения и повторную генерацию исключения. Создать функцию, находящую решения системы линейных уравнений из 3 уравнений от 3 неизвестных методом Крамера. Входными параметрами функции должны быть: 1) двумерный массив 3 на 3 для левой части системы, 2) массив из 3 элементов для правой части, 3) массив для записи решения.

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

2, 6, 10, 14, 18, 22, 26, 30

Описать функцию считывания чисел типа long из текстового потока. Запрограммировать генерацию исключения, в случае если считано не число или число неподходящего формата, выдачу соответствующего сообщения и повторную генерацию исключения.

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

3, 7, 11, 15, 19, 23, 27

Описать функцию извлечения арифметического квадратного корня числа типа double. Функция должна генерировать исключение в случае некорректных данных (аргумент - отрицательное число). В этом случае должно быть выдано соответствующее сообщение и сгенерировано повторное исключение. Создать функцию, находящую корень квадратного уравнения ax2+bx+c=0. Формальными параметрами функции должны быть числа типа double  a, b, c.

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

4, 8, 12, 16, 20, 24, 28

Описать функцию, вычисляющую логарифм по основанию, равному первому аргументу, от числа равного второму аргументу. Функция должна генерировать исключение в случае некорректных данных. В этом случае должно быть выдано соответствующее сообщение и сгенерировано повторное исключение. Создать функцию, находящую методом деления отрезка пополам решение уравнения (здесь x>0 - неизвестное). Формальными параметрами функции должны быть числа типа double  a и точность нахождения корня .

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

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