Язык программирования C++ от Страуструпа


         

Производные особые ситуации


Если для обработки особых ситуаций мы используем иерархию классов, то, естественно, каждый обработчик должен разбираться только с частью информации, передаваемой при особых ситуациях. Можно сказать, что, как правило, особая ситуация перехватывается обработчиком ее базового класса, а не обработчиком класса, соответствующего именно этой особой ситуации. Именование и перехват обработчиком особой ситуации семантически эквивалентно именованию и получению параметра в функции. Проще говоря, формальный параметр инициализируется значением фактического параметра. Это означает, что запущенная особая ситуация "низводится" до особой ситуации, ожидаемой обработчиком. Например:

class Matherr {

  // ...

  virtual void debug_print();

};

class Int_overflow : public Matherr {

  public:

     char* op;

     int opr1, opr2;;

     int_overflow(const char* p, int a, int b)

       { cerr << op << '(' << opr1 << ',' << opr2 << ')'; }

};

void f()

{

  try {

     g();

  }

  catch (Matherr m) {

     // ...

  }

}

При входе в обработчик Matherr особая ситуация m является объектом Matherr, даже если при обращении к g() была запущена Int_overflow. Это означает, что дополнительная информация, передаваемая в Int_overflow, недоступна.

Как обычно, чтобы иметь доступ к дополнительной информации можно использовать указатели или ссылки. Поэтому можно было написать так:

int add(int x, int y)              // сложить x и y с контролем

{

  if (x > 0 && y > 0 && x > MAXINT - y

     || x < 0 && y < 0 && x < MININT + y)

     throw Int_overflow("+", x, y);

     // Сюда мы попадаем, либо когда проверка

     // на переполнение дала отрицательный результат,

     // либо когда x и y имеют разные знаки

  return x + y;

}

void f()

{

  try {

     add(1,2);

     add(MAXINT,-2);

     add(MAXINT,2);                 // а дальше - переполнение

  }

  catch (Matherr& m) {



Содержание  Назад  Вперед