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

advertisement
Лекция № 20
Исключительные
ситуации
Обработка ошибок
Ошибка – исключительная ситуация
(отсутствие файла, сети, недоступен принтер ...)
Много проверок ошибочных ситуаций –
громоздкость кода !
Исключительные ситуации C++
упрощают проверку и обработку ошибок.
Исключительные ситуации - классы.
Операторы обработки ошибок
Оператор try
следит за исключительными ситуациями.
Оператор catch
обнаруживает исключительные ситуации.
Оператор throw генерирует исключительную
ситуацию при возникновении ошибки.
При обнаружении исключительной ситуации
происходит вызов специальной функции,
называемая обработчиком исключительной
ситуации.
Поведение при ошибках
Мы хотим
при встрече с исключительной ситуации
упростить обнаружения и обработки ошибок в
программах.
В идеале, если ваши программы обнаруживают
неожиданную ошибку,
им следует разумным образом ее обработать,
а не просто прекратить выполнение.
Исключительная ситуация – это класс.
В программах определяем каждую исключительную
ситуацию как класс.
Например, следующие ситуации определяют три
исключительные ситуации для работы с файлами:
class file_open_error {};
class file_read_error {};
class file_write_error {};
Проверка исключительных ситуаций
Сначала используем оператор try (попытка) для
разрешения обнаружения исключительной ситуации.
Другими словами пытаемся что-то сделать или
пробуем выполнить операцию.
try
{
file_copy("SOURCE.ТХТ", "TARGET.ТХТ") ;
};
Проверка исключительных ситуаций
После try используем catch, чтобы определить,
какая исключительная ситуация имела место:
try
{ file_copy("SOURCE.ТХТ", "TARGET.ТХТ"); };
catch (file_open_error)
{ printf("Ошибка открытия файла"); exit(1); }
catch (file_read_error)
{ printf("Ошибка чтения"); exit(2); }
catch (file_write_error)
{ printf("Ошибка записи"); exit(3); }
Если вызов успешен и исключительная ситуация не
выявлена, операторы catch игнорируются.
Генерация исключительной ситуации
Можно проверить условие возникновения ошибки и
сгенерировать исключительную ситуацию
при помощи оператора throw.
Использование исключений предполагает, что весь
код выполняется без ошибок, но если ошибка
произошла, то для ее обработки всегда найдется
место в блоке catch.
Обработчик исключительной ситуации
При обнаружении исключительной ситуации,
запускается обработчик исключительной ситуации.
Обработчик исключительной ситуации - функция в
классе исключительной ситуации, с тем же именем.
В идеале обработчик должен выполнить операции,
которые бы исправили ошибку.
После завершения обработки программа
продолжается с первого оператора, следующего за
оператором try.
Обработчик исключительной ситуации
#include <conio.h>
#include <math.h>
#include <iostream>
using namespace std;
class mathERR
{
public:
mathERR(void){ cout << "Invalid arg"<<endl; }
};
float my_sqrt(float x)
{
if (x < 0) throw mathERR();
else return sqrt(x);
}
Обработчик исключительной ситуации
int main(void)
{
float res;
try
{
res = my_sqrt(-10.0);
cout << res;
}
catch (mathERR)
{
cout << "Stop program !";
}
getch();
return 0;
}
try и if
try
{
// попробуем
}
catch(...)
{
// ловим ошибки
}
if (нет ошибки)
{
// выполняем
}
else
{
// прибираем за собой
}
Сходство только на первый взгляд.
В чём разница ?
try и if
Механизм исключений позволяет отлавливать
ошибки место возникновения которых заранее не
известно.
Механизм исключений позволяет отсеивать "чужие"
ошибки.
catch(...) catch(int)
try - catch предназначен для обработки кода,
где заранее не известно будет ошибка или нет,
а проверить наличие ошибки до выполнения
кода часто сложно.
Исключительные ситуации и классы
В класса можно определить исключительные
ситуации, включая её в качестве одного из общих
элементов класса.
class STRING
{
public:
STRING(const char *str);
void show_string(void);
class string_empty {} ;
// строка пустая
class string_overflow {}; // выход за пределы
private:
int length;
char stroka[10];
};
Пример
#include <conio.h>
#include <string.h>
#include <iostream>
using namespace std;
class STRING
{
public:
STRING(const char *str);
void show_string(void);
class string_empty {} ;
class string_overflow {};
private:
int length;
char stroka[10];
};
Пример
STRING::STRING(const char *str)
{
if ((length=strlen(str))>10)
{
length=0; throw string_overflow();
}
strcpy(stroka,str);
}
void STRING::show_string(void)
{
if (strlen(stroka)==0)
{
throw string_empty();
}
cout<<stroka;
}
Пример
int main(void)
{
try
{ STRING QW(""); QW.show_string(); }
catch(STRING::string_empty)
{ cout<<"Empty string...."; }
catch(STRING::string_overflow)
{ cout<<"Overflow........"; }
getch();
return 0;
}
Иерархии исключений
Использование собственных классов исключений
позволяет использовать иерархии классов.
class Matherr{};
class Overflow : public Matherr{}: // Переполнение
class ZeroDivide: public Matherr{}:// Деление
// на ноль
// Ошибки ввода/вывода
class
class
class
class
IOerr{};
Readerr : public IOerr{} ://Ошибка чтения
Writerr : public IOerr{} ://Ошибка записи
Seekerr : public IOerr{} ://Ошибка поиска
Конструкторы и деструкторы
Механизм исключений дает возможность сообщить
об ошибке, возникшей в конструкторе или
деструкторе объекта.
class Vector
{
public:
class Size{}: // Класс исключения
Vector(int n) // Конструктор
{if ((n<0) || (n>16000)) throw Size(); ...}
...
};
try
{Vector *р=new Vector(N);}
catch (Vector::Size){...}
Итоги
1. Исключительная ситуация - класс.
2. try разрешает обнаружение исключительных
ситуаций.
3. catch следует после try, определяет, какая
именно исключительная ситуация имела место.
4.C++ не генерирует исключительные ситуации.
Ваши программы генерируют исключительные
ситуации с помощью оператора throw.
5. При обнаружении исключительную ситуацию,
происходит вызов обработчика.
Download