Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование_на_С++_Ч2_ООП.doc
Скачиваний:
54
Добавлен:
22.02.2015
Размер:
633.34 Кб
Скачать

Виртуальные методы и механизм позднего связывания

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

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». Механизм исключений предназначен только для событий, которые происходят в результате работы самой программы и указываются явным образом.

Исключения позволяют логически разделить вычислительный процесс на две части – обнаружение аварийной ситуации и ее обработку.