Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Полиморфизм и виртуальные функции. Раннее и позднее связывание. Динамический полиморфизм. Виртуальные функции. Виртуальные и невиртуальные функции.

Читайте также:
  1. II. Раннее детство
  2. Аэродинамический расчет дымовой трубы
  3. Аэродинамический расчет систем вентиляции
  4. Аэродинамический расчет систем приточной вентиляции.
  5. Б. Регенерация нервных волокон как фактор, способствующий восстановлению нарушенной функции.
  6. Билет 26. Социальные институты: структура и основные функции.
  7. Бирма в раннее Новое время

Одни и те же сообщения можно посылать объектам родительского класса и объектам всех производных подклассов; это называется полиморфизмом. Полиморфизм позволяет каждому объекту подкласса реагировать некоторым образом на формат сообщения согласно его описанию. Родительский класс содержит основную информацию, общую для всех производных классов, а производные классы хранят дополнительные сведения, касающиеся особенностей конкретного рода занятий. Благодаря полиморфизму, каждому классу можно посылать одно и то же сообщение для ввода данных. Все классы: родительский и производные — соответствующим образом реагируют на это сообщение. Полиморфизм стимулирует расширение существующего кода.

Благодаря полиморфизму, объекты могут реагировать на сообщения из программ, даже если точный тип объекта не известен. В С++ эта возможность является результатом позднего связывания; при этом адреса определяются динамически при выполнении программы, а не статически, во время компиляции — как в обычных транслируемых языках. Статический (фиксированный) процесс часто называют ранним связыванием. Имена функций при этом заменяются адресами памяти. Позднее связывание осуществляется при помощи виртуальных функций, которые определяются в родительском классе, в то время как последующие производные классы перегружают их, переопределяя реализацию конкретной функции. При использовании виртуальных функций сообщения передаются не непосредственно объекту, а в виде указателя, ссылающегося на объект.

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

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

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

class Figure

{

...

virtual void Draw() const;

...

};

class Square: public Figure

{

...

void Draw() const;

...

};

class Circle: public Figure

{

...

void Draw() const;

...

};

Figure * figures[10];

figures[0] = new Square(1, 2, 10);

figures[1] = new Circle(3, 5, 8);

...

for (int i = 0; i < 10; i++)

figures[i]->Draw();

 

При использовании обычных функций вызывается функция базового класса. Это же относится и к деструктору. Если в код используется полиморфизм, то всегда объявляется деструктор базового класса виртуальным. Иначе, при уничтожении всех объектов будет вызываться деструктор базового класса. Вот так правильно:

 

class Base

{

public:

virtual void method ()

{ cout << "Базовый класс\n";}

virtual ~Base()

{}

};

Абстрактные классы (abstract classes) и чистые виртуальные функции (pure virtual functions)

 

Очень часто в программах не требуется создавать объекты базовых классов. Т.е. базовые классы нужны только для того, чтобы построить иерархию классов и определить общие свойства для производных классов. Такие классы можно сделать абстрактными (abstract class). При попытке создания объекта абстрактного класса, компилятор выдаст ошибку.

Чтобы сделать класс абстрактным, нужно объявить одну из виртуальных функций чистой.

Чистая виртуальная функция (pure virtual function) как бы намекает, что она будет реализована в производных классах.

Чтобы сделать виртуальную функцию чистой (pure), нужно добавить после заголовка функции символы =0 (знак равенства и ноль):

class Base

{

public:

virtual void method () =0;

virtual ~Base() =0;

};

Символы =0 необязательно добавлять ко всем виртуальным функциям, достаточно добавить к одной.

 

 


Дата добавления: 2015-12-08; просмотров: 83 | Нарушение авторских прав



mybiblioteka.su - 2015-2024 год. (0.007 сек.)