Бьерн Страуструп - Язык программирования С++. Вступление, глава 1 - Обработка особых ситуаций

ОГЛАВЛЕНИЕ

 

1.4.4 Обработка особых ситуаций

По мере роста программ, а особенно при активном использовании библиотек появляется необходимость стандартной обработки ошибок (или, в более широком смысле, "особых ситуаций"). Языки Ада, Алгол-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.