
- •Структура дисциплины
- •Процедурное программирование
- •Объектно-ориентированное программирование
- •Обобщенное программирование
- •На пути к объектно-ориентированному программированию
- •Абстракция сущностей и процедурный язык программирования
- •Абстрактный тип данных
- •Организация класса
- •Определение и объявление класса
- •Члены класса
- •Маркеры доступа
- •Конструкторы
- •Понятие об объекте
- •Организация кода при работе с классами
- •Статические компоненты класса
- •Конструкторы. Детальное рассмотрение
- •Функции getter и setter
- •Виды отношений между классами
- •Отношение зависимость
- •Отношение целое / часть
- •Разработка класса b_1.
- •Конструктор умолчания.
- •Конструктор с параметрами
- •Конструктор копирования.
- •Деструктор
- •Реализация класса b_2_1.
- •Дружественные функции и дружественные классы
- •Особенности применения дружественных функций и классов
- •Перегрузка оператров
- •Перегрузка оператора присваивания
- •Реализация перегруженного оператора присваивания для класса Array
- •Перегрузка оператора индексирования
- •Понятие о константной функции
- •Константный вариант перегруженного оператора индексирования
- •Вычисление смешанных выражений
- •Наследование
- •Структура объекта порожденного класса
- •Доступ к элементам базового класса
- •Конструкторы порожденного класса
- •Порядок создания объекта порожденного класса
- •Перегруженный оператор присваивания порожденного класса
- •Вызов виртуальной функции из тела невиртуальной функции
- •Виртуализация функций не-членов класса
- •Идиома невиртуального интерфейса (nvi)
- •Реализация механизма виртуальных функций
- •Накладные расходы при работе с виртуальными функциями
- •Чисто виртуальные функции. Абстрактные базовые классы
- •Виртуальные деструкторы
- •Автономные и базовые классы
- •Чисто виртуальный деструктор
- •Дублирование подобъектов
- •Конструкторы при виртуальном наследовании
- •Работа с данными при виртуальном наследовании
- •Обработка исключительных ситуаций
- •Завершение или продолжение
- •Распределение обязанностей между разработчиком и клиентом
- •Генерация исключений
- •Объект исключения
- •Раскрутка стека
- •Спецификации исключений
- •Работа с обработчиками
- •Формат обработчика
- •Пример обработки исключений
- •Современная точка зрения на спецификации исключения
- •Шаблоны функций
- •Объявление и определение шаблона функции
- •Примеры объявлений и определений шаблонов функций
- •Инстанцирование шаблона функции
- •Неявное инстанцирование
- •Явное инстанцирование конкретной функции
- •Структура использования шаблона функции с явным инстанцированием
- •Перегрузка шаблона функции
- •Явная специализация шаблона функции
- •Шаблоны классов
- •Использование шаблона класса
- •Наследование и шаблоны
- •Шаблоны классов и отношение включения
- •Рекурсивное использование шаблонов классов
- •Друзья и шаблоны классов
- •Явная и частичная специализация шаблона класса
- •Алгоритмы
- •Алгоритм for_each
- •Функциональные объекты
- •Алгоритм copy
- •Алгоритм sort
- •Термины и определения
- •.Литература
Объект исключения
Объект исключения автоматически создается компилятором. Он строится на основе того объекта, который «выбрасывает» инструкция throw. Например:
throw std :: length_error(“Недопустимо большой размер ” “объекта \n”);
После того как отработает инструкция throw, временный анонимный объект будет уничтожен. Но перед его уничтожением компилятор снимет копию с этого временного объекта. Эта копия будет сохранена компилятором в надежном месте. Указанная копия и называется объектом исключения. Объект исключения доступен любому обработчику catch, который способен обрабатывать данный тип исключений.
После создания объекта исключения управление должно покинуть тело той функции, в которой сгенерировано исключение. Однако до этого события компьютер должен выполнить так называемую раскрутку стека (stack unwinding).
Раскрутка стека
В процессе раскрутки стека происходит уничтожение локальных объектов. Для локальных объектов, имеющих пользовательский тип, автоматически вызываются деструкторы. Для удаления локальных объектов, имеющих встроенный тип, компилятор ничего не делает. Для объектов, созданных с помощью оператора new, компилятор не будет автоматически вызывать оператор delete с целью принудительного освобождения памяти.
Перейдем теперь к рассмотрению второй обязанности разработчика функции, которая состоит в том, что необходимо уведомить клиента о том какие исключения он должен обрабатывать. Одна из специальных возможностей предусмотрена стандартом языка C++. Эта возможность носит название спецификации исключения.
Спецификации исключений
Это необязательная конструкция. Программист может ее записывать в объявлении и определении функции. Для определенности будем рассматривать объявление (прототип) функции, которое с учетом спецификаций исключения будет иметь следующую структуру.
<α>[β] ;
Здесь α – заголовок функции, β – необязательная спецификация исключения. Отметим, что имеются два формата спецификаций исключения.
-
throw(γ), где γ – список типов исключений.
-
throw().
Второй формат спецификаций исключений используется в тех случаях, когда разработчик функции предполагает, что функция не будет выбрасывать исключения.
Приведем пример.
class A { }; class B { }; class C { }; void f() throw(A, B); void h() throw();
В программном коде этого примера вначале имеются определения трех классов исключений с именами A, B и С. Затем приводятся прототипы двух функций, которые содержат спецификации исключений. Предполагается, что функция f() может выбросить исключения типа A и B. Функция h() не должна выбрасывать исключений.
Теперь казалось бы все хорошо. Клиент знает, что ему необходимо создать два обработчика catch. Один из них должен обрабатывать исключения типа A, а второй обработчик – для типа B.
Но что произойдет в том случае, когда функция выбросит исключение класса C. Это может, например, произойти так:
void f() throw(A, B) { //.. g(); } void g() { //.. throw C(); }
Эта ситуация известна как выброс непредвиденного исключения. Возможность появления такой ситуации усложняет использование спецификаций исключения.