78197

Инициализация и разрушение объектов. Виртуальная функция

Лекция

Информатика, кибернетика и программирование

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

Русский

2015-02-07

68.5 KB

1 чел.

екция: Инициализация и разрушение объектов. Виртуальная функция                                   8 из 8 с

Оглавление

[0.1] ООП: инициализация и разрушение объекта (конструктор и деструктор),
виртуальные методы.

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

[0.1.2] Конструктор

[0.1.3] Деструктор

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

 Лекция №№29-30

ООП: инициализация и разрушение объекта (конструктор и деструктор),
виртуальные методы.
 

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

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

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

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

Рассмотрим пример 2, указанный ниже. Объектовые типы 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) сам конструктор не может быть виртуальным.

Конструктор

Конструктор – это особый метод, который позволяет выполнять некоторую работу, обеспечивающую поддержку механизма виртуальных методов. Он должен вызываться раньше других методов объекта, т.к. он выполняет инициализацию объекта. Вместо слова «procedure» в объявлении объектных типов используется «constructor».

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

Для создания объектов используется расширенный синтаксис вызова функции new, который позволяет выделить память для объекта и инициализировать объект с помощью вызова конструктора. Общий вид инструкции:

Указатель:=new(ТипОбъекта, КонстукторОбъекта);

Деструктор

Для уничтожение объекта служит деструктор. Деструктор объявляется с помощью зарезервированного слова destructor, после которого идет имя деструктора. Деструктор ничего не возвращает и не имеет параметров.

Т.к. объект представляет собой сложную структуру, то рекомендуется использовать метод Done. Метод Done оформляется как деструктор – особая процедура, выполняющая специфическую работу, в том числе обеспечивающая объединение освобождающихся, возможно, небольших участков памяти в более крупные блоки. 

Инструкция Dispose(p,Done); уничтожает объект, на который указывает P.

На практике в качестве конструктора используют метод, устанавливающий начальные значения экземпляра объекта. В частности, конструктор может быть пустым. В рассмотренном примере конструктором является метод Init. Конструктор – это обычный метод-процедура, в котором служебное слово procedure заменено на constructor. Он помимо действий, заданных в его теле, выполняет установочную работу для механизма виртуальных методов, обеспечивая вызов в процессе выполнения программы именно того виртуального метода, который определён для вызывающего объекта. В примере 2 один и тот же метод Moveto будет работать по-разному (передвигать различные фигуры) в зависимости от того, экземпляр какого объектового типа этот метод вызывает. Такое свойство называется полиморфизмом.

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

Текст программы примера 2, использующий виртуальные методы, может быть следующим:

Uses Crt, Graph;

Var gd,gm : integer;

Type Tp=Object

X,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; Show

End;

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;

Procedure Tc.Hide;

Begin

Setcolor(Getbkcolor); Circle(x,y,r)

End;

Var P : Tp;  C : Tc;

Begin

Gd:=Detect;

Initgraph(Gd,Dm,’c:\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;

Closegraph

End.

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

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.

Пример 4. Приведём пример реализации в виде объекта списка целых чисел. В качестве методов будем использовать следующие: инициализацию списка, добавление в список элемента с заданным значением, обработку элементов списка (печать) и  метод, предназначенный для освобождения ранее выделенной памяти.

Type Link=^Rec;

Rec=Record

Inf : Integer;

Next : Link

End;

Tsp=Object

Start : Link;

Procedure Init;

Procedure In_Spisok(X:integer);

Procedure Print_Spisok;

Procedure Done;

End;

Procedure Tsp.Init; Begin Start:=Nil End;

Procedure Tsp.In_Spisok;

Var p : Link;

Begin

New(p);   

P^.inf:=x;   P^.next:=Start;

Start:=p

End;

Procedure Tsp.Print_Spisok;

Var p : Link;

Begin

P:=Start;

While p<>Nil do

Begin

Write(P^.inf:6);

P:=P^.next

End;

End;

Procedure Tsp.Done;

Var p : Link;

Begin

While Start<> Nil do

Begin

P:=Start;

Start:=Start^.next;

Dispose(p)

End

End;

Var Spisok : Tsp;

A : integer;

Ch : char;

Begin

Spisok.Init;

Repeat

Readln(A);

Spisok.In_Spisok(A);

Readln(Ch);

Until Ch in [‘n’,’N’];

Spisok.Print_Spisok;

Spisok.Done

End.

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

  1.  Опишите структуру объекта.
  2.  Дайте определению понятиям «конструктор», «деструктор».
  3.  Дайте определение понятию «виртуальная функция».


 

А также другие работы, которые могут Вас заинтересовать

3777. Brain Ring What? Where? When? 135.5 KB
  Brain Ring What? Where? When? Мета: освітня – закріплення та повторення одержаних знань практична – вчити радити, пропонувати та аргументувати свою думку, сприймати розповідь на слух розвиваюча – розвивати увагу, пізнавальний інт...
3778. Значение института несостоятельности (банкротства) 120.5 KB
  Институт несостоятельности предприятия (банкротства) появился в нашем правовом регулировании в связи с переходом к рыночным отношениям. В условиях всеобъемлющего господства государственной и кооперативно-колхозной собственности проблема пр...
3779. Правоотношения в сфере трудового права 70 KB
  Введение Трудовое право как одна из ведущих отраслей российского права, имеющее предметом регулирования общественные отношения в важнейшей сфере жизнедеятельности общества – в сфере труда, вступило в новый этап реформирования, связанный с приня...
3780. ЖИЗНЬ И ТВОРЧЕСТВО ВИКТОРА МИХАЙЛОВИЧА ВАСНЕЦОВА 75.5 KB
  Виктор Михайлович Васнецов родился в 1848 году в одном из сёл Вятской губернии. В городе Вятке прошла его ранняя юность. В Вятской губернии издавна процветали по сёлам кустарные промыслы, далеко шла слава об искусных вятских умельцах, о резной дерев...
3781. Василий Иванович Суриков 32 KB
  Василий Иванович Суриков В городе Красноярске 24 января 1848 года в семье, принадлежащей к старинному казачьему роду, родился Василий Суриков. С первых сознательных дней своей жизни он жадно впитывает в себя колоритные условия патриархального быта н..
3782. Жизнь и творчество Пабло Пикассо 116.5 KB
  Введение Актуальность выбранной темы я вижу в том, что немногим удавалось достичь такой популярности и силы воздействия на искусство ХХ в., как Пабло Пикассо, родившемуся почти 120 лет назад на юге Испании. Он прожил долгую и плодотворную жизнь. Ког...
3783. Жизнь Льва Ивановича Иванова 44.5 KB
  Жизнь Льва Ивановича Иванова сложилась нелегко, как складывалась жизнь многих русских талантов. Незаконно рожденный, он провёл первые три года в петербургском воспитательном доме, затем был усыновлен отцом и позже отдан в театральное училище. В 1850 г...