153.67K
Категория: ПрограммированиеПрограммирование

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

1.

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ
ПРОГРАММИРОВАНИЕ
Тема 6.
Исключения в С++

2.

Концепция исключений
Исключения
(исключительные
ситуации)

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

3.

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

4.

Генерация, перехват и обработка исключений
#include <iostream>
using namespace std;
void some_function()
{
int exception_id = 1;
throw exception_id; // Генерация целочисленного исключения
}
int main()
{
try // Блок перехвата исключений
{
some_function();
}
catch (int int_exception) // Блок обработки целочисленных исключений
{
cout << "Integer exception" << endl;
}
catch (...) // Блок обработки исключений произвольного типа, не перехваченных ранее
{
cout << "Any other exception" << endl;
}
cout << "End of program" << endl;
return 0;
}

5.

Стандартные исключения C++
В языке С++ в составе стандартной библиотеки реализован ряд стандартных
исключений, которые организованы в иерархию классов. Для использования
стандартных исключений необходимо подключить библиотеку stdexcept. Все
стандартные исключения унаследованы от класса std::exception.
Иерархия стандартных исключений
logic_error – сообщает об ошибках в логике программы
invalid_argument – сообщает об ошибках из-за некорректных значений аргументов функции
domain_error – сообщает об ошибках из-за использования аргументов математических функций,
выходящих за пределы области определения
out_of_range – сообщает об ошибках из-за попытки доступа к элементам за пределами допустимого
диапазона
runtime_error – сообщает об ошибках времени выполнения программы
range_error – сообщает об ошибках из-за несоответствия значения некоторого вещественного числа
диапазону типа данных, которому оно принадлежит
overflow_error – сообщает об ошибках из-за несоответствия значения некоторого целого числа
диапазону типа данных, которому оно принадлежит

6.

Обработка ошибок с помощью исключений C++
#include <iostream>
#include <stdexcept>
#include <ctime>
using namespace std;
int div_function(int a, int b)
{
if (b == 0) throw runtime_error("Division by zero");
return a / b;
}
int main()
{
srand(time(nullptr));
int a = rand() / rand(), b = rand() / rand();
cout << a << "/" << b << " = ";
try
{
cout << div_function(a, b) << endl;
}
catch (exception &e)
{
cout << endl << e.what() << endl;
}
cout << "End of program" << endl;
return 0;
}

7.

Концепция RAII
Получение ресурса есть инициализация (Resource Acquisition Is
Initialization (RAII)) — программная идиома объектно-ориентированного
программирования, смысл которой заключается в том, что с помощью
тех или иных программных механизмов получение некоторого
ресурса неразрывно совмещается с инициализацией, а
освобождение — с уничтожением объекта.
Типичным способом реализации является организация получения
доступа к ресурсу в конструкторе, а освобождения — в
деструкторе соответствующего класса. Поскольку деструктор
переменной вызывается при выходе её из области видимости, то
ресурс гарантированно освобождается при уничтожении переменной.
Это справедливо и в ситуациях, в которых возникают исключения. Это
делает RAII ключевой концепцией для написания безопасного при
исключениях кода.

8.

Пример без RAII
#include <iostream>
using namespace std;
class ClassWithoutRAII
{
private:
int *var;
public:
void Init()
{
var = new int;
*var = 0;
cout << "Variable initialization" << endl;
}
void ExceptionFunction()
{
throw logic_error("Some error");
}
int main()
{
{
ClassWithoutRAII a;
a.Init();
try
{
a.ExceptionFunction();
a.Release();
}
catch (exception &e)
{
cout << e.what() << endl;
}
}
return 0;
}
void Release()
{
delete var;
cout << "Variable release" << endl;
}
};
Без
RAII
не
происходит
автоматическое
освобождение ресурсов при возникновении
исключения.

9.

Пример RAII
#include <iostream>
using namespace std;
class RAIIExample
{
private:
int *var;
public:
RAIIExample()
{
var = new int;
*var = 0;
cout << "Variable initialization" << endl;
}
int main()
{
{
RAIIExample a;
try
{
a.ExceptionFunction();
}
catch (exception &e)
{
cout << e.what() << endl;
}
}
return 0;
}
void ExceptionFunction()
{
throw logic_error("Some error");
}
~RAIIExample()
{
delete var;
cout << "Variable release" << endl;
}
};
English     Русский Правила