Обработка особых ситуаций
По мере роста программ, а особенно при активном использовании библиотек появляется необходимость стандартной обработки ошибок (или, в более широком смысле, "особых ситуаций"). Языки Ада, Алгол-68 и Clu поддерживают стандартный способ обработки особых ситуаций.
Снова вернемся к классу vector. Что нужно делать, когда операции индексации передано значение индекса, выходящее за границы массива? Создатель класса vector не знает, на что рассчитывает пользователь в таком случае, а пользователь не может обнаружить подобную ошибку (если бы мог, то эта ошибка вообще не возникла бы). Выход такой: создатель класса обнаруживает ошибку выхода за границу массива, но только сообщает о ней неизвестному пользователю. Пользователь сам принимает необходимые меры.
Например:
class vector {
// определение типа возможных особых ситуаций
class range { };
// ...
};
Вместо вызова функции ошибки в функции vector::operator[]() можно перейти на ту часть программы, в которой обрабатываются особые ситуации. Это называется "запустить особую ситуацию" ("throw the exception"):
int & vector::operator [] ( int i )
{
if ( i < 0 || sz <= i ) throw range ();
return v [ i ];
}
В результате из стека будет выбираться информация, помещаемая туда при
вызовах функций, до тех пор, пока не будет обнаружен обработчик особой ситуации с типом range для класса вектор (vector::range); он и будет выполняться.
Обработчик особых ситуаций можно определить только для специального блока:
void f ( int i )
{
try
{
// в этом блоке обрабатываются особые ситуации
// с помощью определенного ниже обработчика
vector v ( i );
// ...
v [ i + 1 ] = 7; // приводит к особой ситуации range
// ...
g (); // может привести к особой ситуации range
// на некоторых векторах
}
catch ( vector::range )
{
error ( "f (): vector range error" );
return;
}
}
Использование особых ситуаций делает обработку ошибок более упорядоченной и понятной. Обсуждение и подробности отложим до главы 9.