- •Структура дисциплины
- •Процедурное программирование
- •Объектно-ориентированное программирование
- •Обобщенное программирование
- •На пути к объектно-ориентированному программированию
- •Абстракция сущностей и процедурный язык программирования
- •Абстрактный тип данных
- •Организация класса
- •Определение и объявление класса
- •Члены класса
- •Маркеры доступа
- •Конструкторы
- •Понятие об объекте
- •Организация кода при работе с классами
- •Статические компоненты класса
- •Конструкторы. Детальное рассмотрение
- •Функции getter и setter
- •Виды отношений между классами
- •Отношение зависимость
- •Отношение целое / часть
- •Разработка класса b_1.
- •Конструктор умолчания.
- •Конструктор с параметрами
- •Конструктор копирования.
- •Деструктор
- •Реализация класса b_2_1.
- •Дружественные функции и дружественные классы
- •Особенности применения дружественных функций и классов
- •Перегрузка оператров
- •Перегрузка оператора присваивания
- •Реализация перегруженного оператора присваивания для класса Array
- •Перегрузка оператора индексирования
- •Понятие о константной функции
- •Константный вариант перегруженного оператора индексирования
- •Вычисление смешанных выражений
- •Наследование
- •Структура объекта порожденного класса
- •Доступ к элементам базового класса
- •Конструкторы порожденного класса
- •Порядок создания объекта порожденного класса
- •Перегруженный оператор присваивания порожденного класса
- •Вызов виртуальной функции из тела невиртуальной функции
- •Виртуализация функций не-членов класса
- •Идиома невиртуального интерфейса (nvi)
- •Реализация механизма виртуальных функций
- •Накладные расходы при работе с виртуальными функциями
- •Чисто виртуальные функции. Абстрактные базовые классы
- •Виртуальные деструкторы
- •Автономные и базовые классы
- •Чисто виртуальный деструктор
- •Дублирование подобъектов
- •Конструкторы при виртуальном наследовании
- •Работа с данными при виртуальном наследовании
- •Обработка исключительных ситуаций
- •Завершение или продолжение
- •Распределение обязанностей между разработчиком и клиентом
- •Генерация исключений
- •Объект исключения
- •Раскрутка стека
- •Спецификации исключений
- •Работа с обработчиками
- •Формат обработчика
- •Пример обработки исключений
- •Современная точка зрения на спецификации исключения
- •Шаблоны функций
- •Объявление и определение шаблона функции
- •Примеры объявлений и определений шаблонов функций
- •Инстанцирование шаблона функции
- •Неявное инстанцирование
- •Явное инстанцирование конкретной функции
- •Структура использования шаблона функции с явным инстанцированием
- •Перегрузка шаблона функции
- •Явная специализация шаблона функции
- •Шаблоны классов
- •Использование шаблона класса
- •Наследование и шаблоны
- •Шаблоны классов и отношение включения
- •Рекурсивное использование шаблонов классов
- •Друзья и шаблоны классов
- •Явная и частичная специализация шаблона класса
- •Алгоритмы
- •Алгоритм for_each
- •Функциональные объекты
- •Алгоритм copy
- •Алгоритм sort
- •Термины и определения
- •.Литература
Работа с обработчиками
Перейдем к рассмотрению того, что должен предусмотреть клиент в своем коде. Если кратко сформулировать его действия, то это будет выглядеть следующим образом: блоки try.
Формат блока try.
try <α> <β>
Здесь α – составная инструкция, а β – список обработчиков (блок обработчиков).
Пример.
try { f1(); f2(); // … } // Блок обработчиков. Показан только один обработчик catch(//..) { //.. }
Формат обработчика
catch(<α>) <β>
Здесь α – своего рода единственный формальный параметр, а β – тело обработчика. Если объект внутри тела не используется, то в качестве параметра обработчика может использоваться тип обработчика. Рассмотрим следующий пример.
Вариант 1.
catch(std :: out_of range err) { //.. }
В этом варианте объект исключения передается обработчику catch по значению. Это приведет к созданию временного объекта. Для устранения такого нежелательного явления предпочтительнее принимать объект по ссылке. Это и делается во втором варианте обработчика.
Вариант 2
catch(std :: out_of rang& err) { //.. }
Формальный параметр обработчика может быть так называемым абстрактным объявителем, т. е. информацию только о типе исключения. При этом информация о имени параметра не указывается. Например:
// Код разработчика class MyError { //.. }; // Код клиента
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 «Избегайте спецификаций исключений».
Альтернативой использованию спецификаций исключений может служить написание комментария с указанием возможных исключений.