Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lectures_2.doc
Скачиваний:
28
Добавлен:
15.03.2015
Размер:
511.49 Кб
Скачать

Работа с обработчиками

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

Формат блока try.

try <α> <β>

Здесь α – составная инструкция, а β – список обработчиков (блок обработчиков).

Пример.

try { f1(); f2(); // … } // Блок обработчиков. Показан только один обработчик catch(//..) { //.. }

Формат обработчика

catch(<α>) <β>

Здесь α – своего рода единственный формальный параметр, а β – тело обработчика. Если объект внутри тела не используется, то в качестве параметра обработчика может использоваться тип обработчика. Рассмотрим следующий пример.

Вариант 1.

catch(std :: out_of range err) { //.. }

В этом варианте объект исключения передается обработчику catchпо значению. Это приведет к созданию временного объекта. Для устранения такого нежелательного явления предпочтительнее принимать объект по ссылке. Это и делается во втором варианте обработчика.

Вариант 2

catch(std :: out_of rang& err) { //.. }

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

// Код разработчика classMyError{ //.. }; // Код клиента

catch(MyError) { //.. }

Допустима в обработчике исключения так называемая эллиптическая сигнатура. В этом случае обработчик оказывается совместимым с любым типом исключений. Например:

catch(…) { //.. };

Такой обработчик может реагировать на исключения любого типа. Он должен располагаться последним обработчиком в блоке.

Пример обработки исключений

// Код разработчика class Array { public: enum {MAXSIZE = 20}; struct BadIndex { int index; BadIndex(int index) : index_(index){} }; Array(int capacity = MAXSIZE) { //.. } double& operator[](int index) throw(BadIndex) { if(index >= 0 && index < capacity_) return ptr_[index]; else throw BadIndex(index); } private: int capacity_; double *ptr_; } // Код клиента int main() { Array ar; try { ar[20] = 10; // .. } catch(Array :: BadIndex& err) { cout << “Ошибка BadIndex для значения индекса =” << err.index << endl; } }

Современная точка зрения на спецификации исключения

Ряд авторов не рекомендуют использовать спецификации исключений. К их числу относятся Г. Саттер и А. Александреску, авторы книги «Стандарты программирования на языке C++». В книге содержится совет с номером 75 «Избегайте спецификаций исключений».

Альтернативой использованию спецификаций исключений может служить написание комментария с указанием возможных исключений.

Шаблоны функций

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

Процесс создания определений функций на основе их шаблона называется конкретизацией (инстанцированием) шаблона. Результат инстанцирования называют экземпляром (специализацией) Существуют два вида инстанцирования: явное и неявное.

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

Отметим, что определение шаблона функции следует располагать в заголовочном файле.

Соседние файлы в предмете Программирование