русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Виртуальные функции/методы (virtual functions/methods)


Дата добавления: 2015-07-09; просмотров: 636; Нарушение авторских прав


Чтобы объявить функцию как виртуальную, необходимо добавить ключевое слово virutal перед именем возвращаемого типа:

class Base

{ public: virtual void Method () { cout << "Базовый класс\n"; } };

Вносить изменения в производные классы не нужно. Хотя можно и там добавить ключевое слово virtual (это не обязательно). Теперь посмотрим на наш код:

Base* b = new Derived; Derived* d = new Derived;

b->Method(); d->Method();

//-------- Вывод:

Производный класс Производный класс

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

BaseMonster* monsters[3];

monsters[0] = new MonsterA; monsters[1] = new MonsterB;

for (int i=0;i<3;++i) monsters[i]->attack();

Несколько замечаний по виртуальным функциям:

· Виртуальные функции используются только в классах. Поэтому часто используется название - виртуальные методы.

· В массивах указателей на базовый класс можно хранить объекты только полиморфных типов (базовый и все производные).

· В массив нужно объединять только те объекты, которые обладают методами с одинаковыми названиями, но разной реализацией.

Как видите, пользоваться виртуальными методами очень просто. Теперь давайте разберёмся, какие механизмы стоят за виртуальными функциями.

Таблица виртуальных функций (virtual function table)

Рассмотрим простой код:

class Base

{

public: virtual void vf () { cout << "Базовый класс\n"; } };

 

class Derived : public Base

{ public: void vf () // это тоже виртуальная функция

{ cout << "Производный класс\n"; }

};

Функции Base::vf и Derived::vf являются виртуальными. Об этом говорит ключевое слово virtual в базовом классе. А производный класс наследует это свойство для своего метода.



Для виртуальных методов память выделяется точно так же, как и для обычных: на этапе компиляции под эти методы выделяются участки памяти, первые адреса которых являются адресами методов. Но так как методы виртуальные, то фактические адреса метода не привязывается к именам: Base::vf и Derived::vf. Адрес метода, который назначается на этапе компиляции при выделении памяти, будем называть настоящим (или фактическим) адресом.

Когда в базовом классе объявляется хотя бы одна виртуальная функция, то для всех полиморфных классов создаётся таблица виртуальных функций (virtual function table).

Встречаются разные названия этой таблицы: virtual function table, virtual method table, vtable, vftable.

 

Таблица виртуальных функций - это одномерный массив указателей на функции. Количество элементов в массиве равно количеству виртуальных функций в классе.

Для каждого полиморфного класса (базового и всех производных) создаётся своя таблица виртуальных методов. Количество элементов во всех этих таблицах одинаковое.

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

Помимо создания виртуальной таблицы функций, в базовом классе объявляется поле __vfptr - указатель на vtable. Конечно же, этот указатель наследуется всеми производными классами. __vfptr можно увидеть при отладке.

__vfptr объекта указывает на vtable класса, которому принадлежит объект.

Рассмотрим пример. Допустим, в базовом классе определено две функции: f - не виртуальная и vf - виртуальная:

Base* object = new Derived; object->f();

В данном случае компилятор не обращает внимания, объект какого типа на самом деле хранится в object. Компилятор смотрит на тип указателя и вызывает соответствующий метод - Base::f().

Base* object = new Derived; object->vf();

В данном случае процессор видит, что vf - виртуальный метод. Поэтому он ищет в таблице виртуальных функций нужную запись. Но адрес таблицы виртуальных функций он узнаёт через __vfptr, а этот указатель указывает на таблицу своего класса. Соответственно, будет вызван метод того класса, чей объект вызывает метод vf.

Обратите внимание, что в обоих случаях компилятор отдыхает - он даже не пытается проверить тип объекта, на который указывает указатель. Просто при раннем и позднем связывании методы классов вызываются по-разному.



<== предыдущая лекция | следующая лекция ==>
Полиморфизм (polymorphism) и полиморфные типы (polymorphic types) | Заключение


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.08 сек.