Класс exception определен в стандартной библиотеке (см. п. п. 18.6/1 в [1]) так, как показано в листинге 7.15.
Листинг 7.15. Стандартный класс исключения
class exception { public:
exception () throw();
exception (const exception&) throw();
exception& operator= (const exception&) throw();
virtual -exception () throw();
virtual const char* what () const throwQ;
};
Что означает слово vi rtual, мы разберемся в главе 9, а сейчас обратите внимание на то, что все конструкторы и методы имеют спецификацию, запрещающую генерацию исключений. Это и понятно: если механизм исключений сам будет генерировать исключения, хорошего ждать не придется — программа закончится аварийно.
Как видим, стандартные исключения включают функцию-метод what(), которая, очевидно, выдает строку-сообщение об ошибке. Использование стандартных исключений продемонстрируем с помощью немного модифицированного примера из справочника интегрированной среды С++ Builder 6 (листинг 7.16).
Листинг 7.16. Использование метода what()
#include <stdexcept> #include <1ostream> #include <string> using namespace std;
void f() // функция, генерирующая исключение runtime
{ throw runtime_error("Ошибка runtime!"); } int main () { string s;
try { // контролируем метод replace класса string
s.replace(100,l,l,'c');
}
catch (const exception& e)
{ cout << "Получили исключение: " << e.whatO << endl; }
try { f(); // контролируем нашу функцию
}
catch (const exception& e)
{ cout << "Получили исключение: " << e.whatQ << endl; } return 0;
}
Эта программа выведет на экран две строки:
Получили исключение: basic_string Попучили исключение: Ошибка runtime
В этом простом примере мы Видим два варианта генерации исключений: явный — в нашей функции и неявный — в стандартном методе replace(). Первая строка — это результат работы первого обработчика при неправильном использовании метода replace () строки s, вторая — это уже результат явной генерации исключения типа runtime_error в функции f ().
Обратите внимание на одну замечательную особенность блоков catch: в качестве типа формального параметра используется базовый класс, тогда как при выполнении в обработчик попадает объект-исключение совсем другого типа — наследника от базового. Это очень важное свойство наследования — принцип подстановки — мы рассмотрим при изучении наследования. Кроме того, исключение передается в секцию-ловушку по ссылке. Почему это важно — тоже разберемся при изучении наследования.
В качестве еще одного простого примера можно привести пример использования стандартных исключений в наших динамических классах. Давайте перепишем конструкторы класса ТАггау с применением стандартных исключений. Вместо исключения bad_Range задействуем стандартное исключение range_error, наше исключение bad_Index заменим исключением invalid_argument, а вместо исключения bad_Size используем исключение lengthier го г. Это нам позволит получить в секцию-ловушку диагностическую строку. Новая реализация конструкторов выглядит так, как показано в листинге 7.17.
Листинг 7.17. Конструкторы и методы класса ТАггау со стандартными исключениями // конструкторы
ТАггау::TArray(Uint size, double k) { if (size > 0)
{ size_array = size;
data = new double[size_array];
for(Uint i = 0; i<size_array; ++i) data[i] = k;
}
else throw length__error("Неправипьно задан размер массива");
}
TArray::TArray(const double *begin, const double *end)
{ if (begin < end) // защита
{ size_array = (end - begin); data = new double[size_array];
for(Uint i = 0; i<size_array; ++i) data[i] = *(begin+i);
}
else throw range_error("HenpaBnnbHbiii диапазон указателей");
}
TArray::TArray(const TArray &a, Uint begin, Uint k) { if ((begin<a.size())&&(k<a.size()-begin)) { size__array = k; data = new double[size_array]; for(Uint i = 0; i<size_array; ++i) data[i] = a.data[i+begin];
}
else throw invalid_argument("HenpaBHnbHbiii индекс ");
}
Использование стандартных исключений позволяет написать единственный обработчик исключений с параметром типа exception, который будет перехватывать все генерируемые исключения. А конкретную причину мы узнаем, использовав в секции-ловушке метод what (), как в предыдущем примере. |