double arrow

Замечание №4

Замечание №3

Замечание №2

Замечание №1

Конструкторы.

Виртуальные методы.

Полиморфизм. Конструкторы.

Методы класса могут объявляться в C++ как виртуальные. К механизму виртуальных методов обращаются в тех случаях, когда в родительский класс необходимо поместить функцию, которая должна по-разному выполняться в дочерних классах. Точнее, по-разному должна выполняться не единственная функция из родительского класса, а в каждом дочернем классе требуется свой вариант этой функции. Любой нестатический метод родительского класса может быть сделан виртуальным, если в его объявлении использовать спецификатор virtual.

class base { public: virtual void f1 (void); }

Если в родительском классе объявлен какой – либо виртуальный метод, то это накладывает следующие ограничения на все дочерние классы. { Все наследники виртуального метода должны быть виртуальными. Заголовки всех реализаций (вниз по иерархии) одноименных виртуальных методов должны быть одинаковыми. (имя метода, количество и тип параметров совпадают). Каждый класс, в котором описан данный метод должен содержать конструктор.}

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

Class tPoint {

Private: ….;

Public: tPoint ();

//…..

;}

Работа с конструктором аналогична работе с другими методами. Конструктор является виртуальным методом, поэтому слово virtual не указывается. Основное назначение – установка связей с таблицей виртуальных методов.

Относительно конструкторов имеют место такие правила:

1. Для него не объявляется тип возвращаемого значения.

2. Он не может возвращать значений оператором return.

3. Конструктор не наследуется.

4. Конструктор не может быть объявлен как const, volatile, virtual или static.

Перед тем как вызвать метод, необходимо вызвать конструктор (при использовании виртуальных методов). Иначе не произойдёт связи с таблицей виртуальных методов.

Конструктор может содержать любые команды.

Каждый отдельный объект должен быть инициализирован отдельным вызовом конструктора.

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

Пр.2.7 Изменённый пр.2.6

1) Move, Hide, Draw – сделаем виртуальными.

2) Move – вынесем в родительский класс tlocation.

3) Move – уберём из tEllipse и tPoint.

4) Init – constructor.

Type tlocation = object;

x, y: integer;

constructor Init (InitX, InitY: integer);

procedure Move (NewX, NewY); virtual;

procedure Hide; virtual;

procedure draw; virtual;

end;

tPoint = object(tlocation);

color: word;

constructor Init(InitX, InitY, col);

procedure Hide; virtual;

procedure Draw; virtual;

end;

tEllipse = object(tPoint);

Rx, Ry: word;

procedure Init(InitX, InitY, col, NRx, Nry);

procedure Hide; virtual;

procedure Draw; virtual;

end;

{методы tlocation}

constructor tlocation.Init();

begin

x:=InitX;

y:=InitY;

end;

procedure tlocation.Move(NewX, NewY)

begin

Hide;

x:= NewX;

y:= NewY;

Draw;

End;

Procedure tlocation.Hide;

Begin

End;

Procedure tlocation.Draw;

Begin

End;

{методы tPoint}

constructor tPoint.Init();

begin

tlocation.Init();

color:=col;

end;

§11. Таблицы виртуальных методов. VMT – Virtual Method Table.

VMT – структура, содержащая адреса виртуальных методов. Каждый класс, содержащий виртуальный метод имеет таблицу виртуальных методов.

(1) - Размер в байтах всех полей класса.

(2) – Отрицательный размер.

(3), (4), (5) – Адреса виртуальных методов.

Сколько методов столько и позиций.

VMT – tlocation VMT - tPoint

Адрес tlocation.Draw  
Адрес tPoint.Draw
Адрес tPoint.Hide
Адрес tlocation.Move
-6б
Адрес tlocation.Hide  
Адрес tlocation.Move
-4б
4б(x, y: integer x+y= 2+2 = 4б)

В отличии от статических методов в теле виртуальных методов записаны не адреса методов, а смещение по таблице VMT того класса, объект которого вызывает метод tlocation.Move (после компиляции).

Проявление полиморфизма, метод Move – 1, в нём есть изменяемые части и он может принимать различные формы.

Var pp:tPoint;

Begin

Pp::Init();

Pp::Move();

I. 1) pp.Init; - инициализация.

2) У каждого объекта существует неявное поле self, в котором конструктор записывает адрес VMT того класса к которому относится объект вызывающий данный конструктор.

II. pp.Move();

Цепочка вызовов

 
 


Tlocation::Move(в (3) VMT tPoint)

 
 


tPoint::Hide(VMT(4))

 
 


x, y


tPoint::Draw(VMT(5))

Адреса одноимённых методов во всех таблицах виртуальных методов должны занимать позицию с одинаковыми номерами Hide в (4), Draw в (5).

Метод tlocation.Move является полиморфическим, так как в нём присутствуют заменяемые части и поэтому он может подстраиваться под вызывающий его объект. Это есть проявление полиморфизма, То есть множественность форм одного и того же метода. Выделение памяти для таблицы виртуальных методов осуществляется статически и заполняется она тоже статически во время компиляции.

Из tEllipse убрали Hide и Draw.

tEllipse pel;

{

Pel::Init();

Pel::Move();

VMT в этом случае

tEllipse

(1) Если из класса tEllipse убрать методы Hide и Draw то тогда на (3)

--------//--------  
tlocation.Move, а (4) и (5) наследуются у предков.

(2)

 
 
Tlocation::Move


(3)

 
 
tPoint::Hide


(4)

   
 
--------//--------
 
 
tPoint::Draw  


(5)


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



Сейчас читают про: