Хелпикс

Главная

Контакты

Случайная статья





Оглавление. Виртуальные функции



Оглавление

ООП: Виртуальные функции................................................................................................................................................................. 1

Контрольные вопросы.................................................................................................................................................................................. 3

 Лекция №30

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

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

Виртуальный метод (виртуальная функция) — это метод (или функция) объекта, который может быть переопределён в объектах-наследниках так, что конкретная реализация метода для вызова будет определяться только во время исполнения. Таким образом, программисту необязательно знать точный тип объекта для работы с ним через виртуальные методы: достаточно лишь знать, что объект принадлежит родителю или наследнику, в котором метод объявлен.

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

Рассмотрим пример 5, указанный ниже. Объектовые типы Tp и Tc содержат поля и методы для рисования, стирания и передвижения точек и окружностей на экране дисплея. Эти два объектовых типа связаны отношениями наследования и содержат одноимённые методы Show (нарисовать), Hide (удалить с экрана) и Moveto (передвинуть). Для различных геометрических фигур алгоритмы методов Show и Hide существенно отличаются. Алгоритм метода Moveto для обеих фигур одинаков (удалить фигуру со старого места, изменить координаты размещения фигуры и нарисовать ту же фигуру на новом месте).Естественным является желание определить метод Moveto для объектового типа Tp и наследовать этот метод без переопределения во всех типах объектов-потомков. Поясним невозможность такого подхода в данной проблеме без дополнительных затрат.Допустим, что метод Moveto определён только в объектовом типе Tp. Если имеются экземпляры двух объектов: var P : Tp; C : Tc;, то вызов метода P.Moveto начнёт своё выполнение с метода Tp.Hide. Последующие действия метода Moveto приведут к ожидаемому результату. Теперь рассмотрим вызов C.Moveto. Экземпляр типа-потомка вызывает унаследованный метод Moveto, который жёстко связан с методами Tp.Show и Tp.Hide. Методы Show, Hide, Moveto были откомпилированы в одном контексте – в одном объектовом типе Tp . Поэтому метод Moveto всегда будет вызывать методы Tp.Show и Tp.Hide. Связь этих методов является статической, так как она была определена при компиляции. Методы С.Show и С.Hide вызваны не будут. Вызов С.Moveto приведёт к перемещению точки.Если мы хотим иметь один метод Moveto для различных объектов, необходимо разорвать статическую связь этого метода с методами Show иHide и обеспечить возможность для метода Moveto вызывать либо методы Tp.Show и Tp.Hide, либо .Show и .Hide в зависимости от того, какой объект вызывает метод Moveto. Такой механизм называют динамическим или поздним связыванием в отличие от статического или раннего связывания. Он достигается введением виртуальных методов.Для определения метода как виртуального после заголовка метода в объектовом типе указывается служебное слово VIRTUAL.При виртуализации методов должны выполняться следующие условия:1) если прародительский объектовый тип описывает метод как виртуальный, производные типы метод с тем же именем также должны описывать как виртуальный;2) заголовок в заново определённом виртуальном методе не может быть изменён;3) если объектовый тип содержит виртуальный метод, он должен содержать хотя бы один метод-конструктор;4) метод-конструктор должен быть применён к экземпляру объекта до первого вызова виртуального метода;5) каждый экземпляр объекта должен быть инициализирован отдельным вызовом конструктора;6) сам конструктор не может быть виртуальным.Пример 5. Текст программы, использующий виртуальные методы, может быть следующим:Uses Crt, Graph;Var gd,gm : integer;Type Tp=ObjectX,y,c : integer;

Constructor Init(ax,ay,ac : integer);

Procedure Show; Virtual;

Procedure Hide; Virtual;

Procedure Moveto(dx,dy : integer);

End;

Constructor Tp.Init;

Begin X:=ax; y:=ay; c:=ac End;

Procedure Tp.Show;

Begin Putpixel(x,y,c); End;

Procedure Tp.Hide;

Begin Putpixel(x,y,Getbkcolor) End;

Procedure Tp.Moveto;

Begin

Delay(1000); Hide;

X:=x+dx; y:=y+dy; ShowEnd; Type Tc=Object(Tp)       R : integer;

Constructor Init(ax,ay,ac,ar : integer);

Procedure Show; Virtual;

Procedure Hide; Virtual;

End;

Constructor Tc.Init;

       Begin Inherited(ax,ay,ac); R:=ar End;

Procedure Tc.Show;

       Begin       Setcolor(c); Circle(x,y,r)       End;

ProcedureTc.Hide;

       Begin       Setcolor(Getbkcolor); Circle(x,y,r)       End;Var P : Tp; C : Tc;BeginGd:=Detect;Initgraph(Gd,Dm,’d:\bp\bgi’);

P.Init(100,120,yellow);

P.Show; P.Moveto(50,50);

Readln;

C.Init(200,300,Green,150);

C.Show; C.Moveto(10,10);

Readln;ClosegraphEnd. Пример 6. Пример использования виртуальных методов при работе с вектором и матрицей (предусмотрим ввод значений элементов рассматриваемой структуры данных, нахождение в структуре элемента с минимальным значением и вывод результата).const nmax=10;type tvect = array[1..nmax] of real;tmatr = array[1..nmax,1..nmax] of real;vect = object       n:integer;{фактический размер вектора, количество строк матрицы }       min : real;       a : tvect;       constructor init;       procedure inpt ; virtual; {ввод}       procedure obr ; virtual; {нахождение минимального элемента}       procedure out; {вывод}       procedure work;{полная обработка структуры данных}       end;constructor vect.init; begin end;procedure vect.inpt;var i : integer;begin       writeln('n=?'); readln(n);       for i:=1 to n do       begin       write('a[i]-?'); readln(a[i])       end;end;procedure vect.obr;var i : integer;begin       min:=a[1];       for i:=2 to n do       if a[i]<min then min:=a[i]end;procedure vect.out;begin writeln('min=',min:7:3) end;procedure vect.work;begin inpt; obr; out end; type matr=object(vect)       m : integer; {количество столбцов матрицы}       b : tmatr;       procedure inpt; virtual;{ввод}       procedure obr; virtual;{нахождение мин. элемента}       end;procedure matr.inpt;var i,j : integer;begin       writeln('n,m=?'); readln(n,m);       for i:=1 to n do       for j:=1 to m do       begin       writeln('b[i,j]=?'); readln(b[i,j])       end;end;procedure matr.obr;var i,j : integer;begin       min:=b[1,1];       for i:=1 to n do       for j:=1 to m do       if b[i,j]<min then min:=b[i,j]end; var ObjVect : vect; ObjMatr : matr;begin ObjVect.init; ObjVect.work; ObjMatr.init; ObjMatr.work;readln end.

Контрольные вопросы

1. Дайте определение понятию «виртуальная функция».



  

© helpiks.su При использовании или копировании материалов прямая ссылка на сайт обязательна.