- •А. В. Кибардин
- •Оглавление
- •Введение
- •Классы Описание класса
- •Описание объектов
- •Указательthis
- •Конструкторы
- •Конструктор копирования
- •Конструктор копирования для класса monstr:
- •Статические элементы класса
- •Статические поля
- •Статические методы
- •Дружественные функции и классы Дружественные функции
- •Дружественный класс
- •Деструкторы
- •Перегрузка унарных операций
- •Перегрузка бинарных операций
- •Перегрузка операции присваивания
- •Перегрузка операции приведения типа
- •Наследование Ключи доступа
- •Простое наследование
- •Правила наследования методов
- •Виртуальные методы и механизм позднего связывания
- •Абстрактные классы
- •Обработка исключительных ситуаций
- •Синтаксис исключений
- •Перехват исключений
- •Список исключений
- •Иерархии исключений
- •Стандартная библиотека
- •Потоковые классы
- •Стандартные потоки
- •Форматирование данных
- •Флаги и форматирующие методы
- •Манипуляторы
- •Методы обмена с потоком
- •Ошибки потоков
- •Файловые потоки
- •Строковые потоки
- •Конструкторы и присваивание строк
- •Операции
- •Функции Присваивание и добавление частей строк
- •Преобразование строк
- •Поиск подстрок
- •Сравнение частей строк
- •Получение характеристик строк
- •Контейнерные классы
- •Последовательные контейнеры
- •Векторы
- •Двусторонние очереди
- •Ассоциативные контейнеры
- •Словари
- •Словари с дубликатами (multimap)
- •Приложение 1. Шаблоны функций
- •Приложение 2. Шаблоны классов
- •Библиографический список
- •В трех частях
Виртуальные методы и механизм позднего связывания
Работа с объектами ведется чаще всего через указатели. Указателю на базовый класс можно присвоить значение адреса объекта любого производного класса, например:
monstr *p;
p = new daemon;
Вызов методов объекта производится в соответствии с типом указателя, а не фактическим типом объекта, на который он ссылается.
Пример
p -> draw (1, 1, 1, 1); // вызывается метод класса monstr, а не класса daemon.
Этот процесс называется ранним связыванием и выполняется на этапе компоновки программы. Для того чтобы вызвать метод класса daemon, можно использовать явное преобразование типа указателя:
((daemon *p)) - > draw (1, 1, 1, 1);
Это не всегда возможно, поскольку указатель в разное время может ссылаться на разные объекты разных классов иерархии.
В С++ реализован механизм позднего связывания, когда разрешение ссылок на метод происходит на этапе выполнения программы в зависимости от конкретного типа объекта, вызвавшего метод. Этот механизм реализован с помощью виртуальных методов.
Для определения виртуального метода используется спецификатор virual:
virtual void draw (int x, int y, int scale, int position);
Правила описания и использования виртуальных методов:
– если в базовом классе метод определен как виртуальный, метод, определенный в производном классе с тем же именем и набором параметров, автоматически становится виртуальным, а с отличающимся набором параметров – обычным.
– виртуальные методы наследуются;
– если виртуальный метод переопределен в производном классе, объекты этого класса могут получить доступ к методу базового класса с помощью операции доступа к области видимости;
– виртуальный метод не может объявляться с модификатором static, но может быть объявлен как дружественный;
– если в классе вводится описание виртуального метода, он должен быть определен хотя бы как чисто виртуальный (см. далее «Абстрактные классы»);
Чисто виртуальный метод содержит признак = 0 вместо тела, например:
virtual void f (int) = 0;
Если определить метод draw в классе как виртуальный, решение о том, метод какого класса вызывать, решается в зависимости от типа объекта, на который ссылается указатель:
monstr *r, *p;
r = new monstr;
p = new daemon;
r - > draw (1, 1, 1, 1); // вызывается метод класса monstr
p - > draw (1, 1, 1, 1) // вызывается метод класса daemon
p - > monstr :: draw (1, 1, 1, 1); // обход механизма виртуальных методов
Если объект класса daemon будет вызывать метод draw не непосредственно, а косвенно (т. е. из другого метода, определенного в классе monstr), будет вызван метод draw класса daemon.
Абстрактные классы
Класс, содержащий хотя бы один чисто виртуальный метод, называется абстрактным. Абстрактные классы предназначены для представления общих понятий, которые предполагается конкретизировать в производных классах. Абстрактный класс может использоваться только в качестве базового класса для других классов – нельзя создавать объекты абстрактного класса.
Обработка исключительных ситуаций
Исключительная ситуация, или исключение, – это возникновение непредвиденного или аварийного события, которое может порождаться некорректным использованием аппаратуры. Например, это деление на ноль или обращение по несуществующему адресу памяти. Обычно такие события приводят к завершению программы с системным сообщением об ошибке. С++ дает программисту возможность восстановить программу и продолжить ее выполнение.
Исключения С++ не поддерживают обработку асинхронных событий, таких как ошибки оборудования или обработку прерываний, например одновременное нажатие «Crtl» и «C». Механизм исключений предназначен только для событий, которые происходят в результате работы самой программы и указываются явным образом.
Исключения позволяют логически разделить вычислительный процесс на две части – обнаружение аварийной ситуации и ее обработку.