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.  Дайте определение понятию «виртуальная функция».


 

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

67791. Дослідження електричних кіл з послідовним, паралельним та змішаним з’єднанням опорів 279.5 KB
  Вивчити експериментальні методи дослідження електричних кіл з послідовним, паралельним і змішаним з’єднанням опорів. Навчитись визначати еквівалентні опори при різних способах їх з’єднання та потужності, що споживають окремі опори та електричні кола.
67792. Дослідження складних кіл постійного струму 275 KB
  Вивчити методи розрахунку складних електричних кіл і експериментально перевірити метод еквівалентного генератора. Використовувати описані вище методи у цьому випадку недоцільно бо розроблено метод еквівалентного генератора метод холостого ходу і короткого...
67793. Дослідження впливу навантаження на режими роботи джерела постійного струму. Нелінійні електричні кола 278.5 KB
  Дослідити вплив навантаження на основні характеристики передачі енергії джерелом постійного струму. Навчитися досліджувати нелінійні електричні кола. Короткі теоретичні відомості Будь-яке електричне коло складається з джерела електричної енергії, споживача та лінії передачі і його можна представити електричною схемою...
67794. Дослідження магнітного кола постійних струмів 576.5 KB
  Вивчити методи та прилади вимірювання магнітної індукції і магнітного потоку та дослідити веберамперні характеристики магнітних кіл постійного струму. Короткі теоретичні відомості Частину електротехнічного пристрою призначеного для створення в його робочому об’ємі магнітного поля заданої...
67795. Дослідження послідовного кола змінного струму 423 KB
  Перевірка закону Ома при аналізі послідовних кіл змінного струму, які складаються з активного опору, індуктивності і ємності, і вивчення явища резонансу напруг. Короткі теоретичні відомості Змінним називається струм, який періодично змінює свій напрямок. Напруга змінного синусоїдного струму описується функцією...
67796. Дослідження електричного кола змінного струму з паралельним з’єднанням віток 333.5 KB
  Дослідити режим роботи електричного кола з паралельним з’єднанням котушки індуктивності і ємності при різних частотах вивчити вплив С і L на явище резонансу струмів та його використання для регулювання коефіцієнта потужності. Короткі теоретичні відомості На відміну від кола...
67797. Дослідження трифазної системи при з’єднанні споживачів зіркою 515.5 KB
  Вивчити основні властивості і застосування трифазних кіл при з’єднанні джерела і споживачів зіркою. Дослідити роботу трифазної системи струмів при рівномірному і нерівномірному навантаженні фаз а також роботу системи при обриві фазного і нульового проводів.
67798. РЕНТГЕНОГРАФИЧЕСКОЕ ОПРЕДЕЛЕНИЕ ОРИЕНИРОВКИ НЕОГРАНЕННЫХ МОНОКРИСТАЛЛОВ МЕТОДОМ ЛАУЭ 2.04 MB
  В методе Лауэ дифракционная картина получается от неподвижного монокристалла при облучении его непрерывным спектром рентгеновского излучения. Образцом может служить как изолированный кристалл, так и достаточно крупное зерно поликристалла.