Исключения возникают при какой-либо ошибке в программе, а также при ее искусственной генерации в программе. Например, при попытке открыть файл с неверным именем операционная система сгенерирует исключение с соответствующим номером. Из программы мы можем сгенерировать исключение с помощью оператора throw. Примеры:
throw 123;
throw “Исключительная ситуация 2”;
Для обработки исключений используется оператор try … catch.
При возникновении исключения C++ первым делом копирует сгенерированный объект в некоторое нейтральное место. После этого просматривается конец текущего блока try. Если блок try в данной функции не найден, управление передается вызывающей функции, где и осуществляется поиск обработчика. Если и здесь не найден блок try, процесс повторяется далее, вверх по стеку вызывающих функций. Этот процесс называется разворачиванием стека. Важной особенностью разворачивания стека является то, что на каждом его этапе все объекты, которые выходят из области видимости, уничтожаются так же, как если бы функция выполнила команду return. Это оберегает программу от потери ресурсов и действий неуничтоженных объектов. Когда необходимый блок try найден, программа ищет первый блок catch (который должен находиться сразу за закрывающей скобкой блока try). Если тип сгенерированного объекта совпадает с типом аргумента, указанным в блоке catch, управление перелается этому блоку (при этом аргументу catch будет присвоено значение объекта исключения); если же нет, проверяется следующий блок catch. Если в результате подходящий блок не найден, программа продолжает поиск уровнем выше, пока не будет обнаружен необходимый блок catch. Если искомый блок так и не найден, программа аварийно завершается. Возможно написание catch (…). Это соответствует любому типу и значению объекта исключения.
Пример с генерацией своего исключения:
#include <iostream.h>
//factorial - вычисляет факториал
int factorial(int n)
{
// Поскольку функция не может работать с
// отрицательными n, мы сразу проверяем
// допустимость переданного аргумента
if (n<0) throw "Отрицательный аргумент";
// теперь вычислим факториал
int accum=1;
while(n>0)
{
accum*= n;
n--;
}
return accum;
}
int main(int arges, char *pArgs[])
{
try
{
// Эта строка генерирует исключение
сout<<"Факториал от -1 равен"<<factorial(-1)<<endl;
// Управление никогда не дойдет до этой строки
cout<<" Факториал от 10 равен "<<factorial(10)<<endl;
}
// управление будет передано сюда
catch (char *pError)
{
cout<<"Возникла ошибка: " <<pError<<endl;
}
return 0;
}
Пример с исключительной ситуацией при записи на диск: