Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Глава 7. Обработка исключительных ситуаций

229

catch(Vector::Size){

... // Обработка ошибки размера вектора

} В обработчике может использоваться стандартный набор основных способов выдачи сообщений об ошибке и восстановления. Внутри класса, определяющего исключение, может храниться информация об исключении, которая передается обработчику. Смысл этой техники заключается в том, чтобы обеспечить передачу информации об ошибке из точки ее обнаружения в место, где для обработки ошибки имеется достаточно возможностей.

Если в конструкторе объекта генерируется исключение, автоматически вызываются деструкторы для полностью созданных в этом блоке к текущему моменту объектов, а также для полей данных текущего объекта, являющихся объектами, и для его базовых классов. Например, если исключение возникло при создании массива объектов, деструкторы будут вызваны только для успешно созданных элементов.

Если объект создается в динамической памяти с помощью операции new и в конструкторе возникнет исключение, память из-под объекта корректно освобождается.

Иерархии исключений

Использование собственных классов исключений предпочтительнее применения стандартных типов данных. С помощью классов можно более гибко организовать передачу информации об исключении, легче дифференцировать обработку исключений, а кроме того, появляется возможность использовать иерархии классов.

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

class Matherr{};

class Overflow: public Matherr{}: // Переполнение

class Underflow: public Matherr{}; // Исчезновение порядка

class ZeroDivide: public Matherr{}; // Деление на ноль

Для представления ошибок ввода/вывода могут использоваться следующие классы:

class Юегг{}:

class Readerr: public Юегг{}; // Ошибка чтения

class Writerr: public Юегг{}: // Ошибка записи

class Seekerr: public Юегг{}; // Ошибка поиска

В зависимости от обстоятельств можно использовать либо обработчик исключений базового класса, который будет перехватывать и производные исключения, либо собственные обработчики производных классов.

230 Часть II. Объектно-ориентированное программирование

Существует ряд стандартных исключений, которые генерируются операциями или функциями C++ (см. главу 16 «Другие средства стандартной библиотеки», с. 378). Все они являются производными от библиотечного класса exception, описанного в заголовочном файле <stdexcept>. Например, операция new при неудачном выделении памяти генерирует исключение типа bad_alloc.

Программист может определить собственные исключения, производные от стандартных.

Глава 8

Преобразования типов

При выполнении программы производятся явные и неявные преобразования величин из одного типа в другой. Неявные преобразования выполняются в соответствии с правилами, приведенными на с. 38 и в приложении 3. Для выполнения явных преобразований типа в C++ существует целая группа операций — const_cast, dynamic_cast, reinterpret_cast и static_cast, а также операция приведения типа, унаследованная из языка С, которая уже использовалась в этой книге (с. 56). Для начала рассмотрим ее подробнее.

Операция приведения типов в стиле С

Операция может записываться в двух формах:

тип (выражение) (тип) выражение

Результатом операции является значение заданного типа, например:

int a = 2;

float b = 6.8;

printfCSlf %6". double (a), (int) b);

Величина а преобразуется к типу double, а переменная b — к типу int с отсечением дробной части, в обоих случаях внутренняя форма представления результата операции преобразования иная, чем форма исходного значения.

Необходимость в преобразовании типа возникает, например, в случае, когда функция возвращает указатель на тип void, который требуется присвоить переменной конкретного типа для последующего выполнения с ней каких-либо действий:

float *q = (float *) mallocdOO * sizeof(float)):

Явное преобразование типа является источником возможных ошибок, поскольку вся ответственность за его результат возлагается на программиста. Поэтому в C++ введены операции, позволяющие выполнять частичный контроль выпол-

232