Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

Виртуальные элементы-функции



Виртуальная функция - это элемент-функция базового класса в иерархии наследования со спецификатором virtual, переопределенная в производных классах и вызываемая в зависимости от класса объекта, адресуемого через указатель или ссылку на базовый класс.

Виртуальная функция имеет следующие свойства:

- определяется в базовом классе иерархии наследования со словом virtual и переопределяется в производных классах;

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

- не может быть объявлена как static, так как наследуется;

- выбор соответствующего экземпляра функции производится через указатель (или ссылку) на базовый класс в зависимости от типа (класса) объекта, адресуемого указателем (или ссылкой), а не в зависимости от типа указателя (или ссылки);

- вызывается динамически во время выполнения программы, что приводит к увеличению времени выполнения.

Пусть имеется иерархия классов, показанная на рис. 3.5, в каждом из которых содержится элемент-функция void vyvod().

cl1 //работники предприятия

|

cl2 //работники цеха

|

cl3 //рабочий участка

Рис. 3.5. Иерархия классов

Требуется составить программу последовательного вызова функций vyvod() классов cl1, cl2, cl3.

Приведем следующие рассуждения. Так как каждый работник цеха и участка являются работниками предприятия, то указатели (или ссылки) на cl2 и cl3 можно присвоить указателям (или ссылкам) на cl1, т.е. объекты производных классов можно рассматривать, как объекты базового класса:

- объявление объектов: cl1 obj1; cl2 obj2; cl3 obj3;

- объявление указателей (или ссылок) на класс cl1: cl1* p[3]; или

cl1& r1; cl1& r2; cl1& r3;

- присваивание указателям (или ссылкам) на класс cl1 указатели (или ссылки) на классы cl2 и cl3: p[0]=&obj1; p[1]=&obj2; p[2]=&obj3; или r1=obj1; r2=obj2; r3=obj3;

Итак, вызываются последовательно экземпляры виртуальной функции vyvod() классов cl1, cl2, cl3, что и было необходимо.

Позднее (динамическое) связывание заключается в том, что связывание вызова функции с необходимым экземпляром функции осуществляется динамически во время выполнения программы. Вызов функции обрабатывается в пределах своего полиморфического кластера. Полиморфический кластер - это совокупность классов, в которых определяется и переопределяется виртуальная функция. Для каждого класса кластера создается таблица виртуальных функций (VT), содержащая адреса этих функций. Каждый объект класса получает скрытый указатель (VP) на соответствующую таблицу VT, который неявно инициализируется (с помощью конструктора) адресом таблицы VT и смещением в таблице VT адреса функции. Пример представлен в табл. 3.3.

Таблица 3.3.

Объекты классов Таблицы VT Функции классов
obj1: VP=(a1, hvyvod)---à //VT_cl1: -->a1)...(a1_vyvod)--à -->a1_vyvod)void vyvod() {...}
obj2: VP=(a2, hvyvod)---à //VT_cl2: -->a2)...(a2_vyvod)--à -->a2_vyvod)void vyvod() {...}
obj3: VP=(a3, hvyvod)---à //VT_cl3: -->a3)...(a3_vyvod)--à -->a3_vyvod)void vyvod() {...}

Рассмотрим алгоритм вызова функции vyvod() класса cl3:

- по адресу объекта в указателе (p[2]=&obj3;) находится объект (obj3) и определяется указатель VP на таблицу виртуальных функций VT (VP=(a3,hvyvod)), содержащий адрес таблицы (a3) и смещение в таблице VT адреса функции (hvyvod);

- по адресу таблицы (a3) и смещению (hvyvod) в таблице VT находится адрес виртуальной функции (a3_vyvod);

- по адресу функции (a3_vyvod) находится функция vyvod() класса cl3.





Дата публикования: 2014-11-26; Прочитано: 1008 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.006 с)...