Справочник по C/C++
Обработка исключений

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

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

try{
	//блок_trу
}
catch (тип1 arg) {
	//блок_саtch_l
}
catch (тип2 arg) {
	//блок_catch_2
}
catch (типЗ arg) {
	//блок_сatch_3
}
// . . .
catch (типN arg) {
	//блок_catch_N
}

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

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

Оператор throw генерирует исключение. Вот как выглядит общая форма оператора throw,

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

Оператор throw должен выполняться либо из самого блока try, либо из любой функции, вызываемой(прямо или косвенно) из блока try. Элемент исключение представляет собой "выбрасываемое" в этот критический момент значение.

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

Пример

#include <iostream>
using namespace std;
int main()
{
	cout << "Начало\n";
	try { // начало блока try
		cout << "Внутри блока try\n";
		throw 100;		// генерируем ошибку
		cout << "Этот оператор выполнен не будет";
	}
	catch (int i) { 		// перехватываем ошибку
		cout << "Перехватываем исключение - ";
		cout << "значение равно: ";
		cout << i << "\n";
	}

	cout << "Конец";

	return 0;
}

При выполнении этой программы будут выведены следующие сообщения.

Начало
Внутри блока try
Перехватываем исключение - значение равно: 100
Конец

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