Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пособие по Паскалю 3.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
313.34 Кб
Скачать

2.5. Отличие виртуальных и динамических методов

Динамические методы отличаются от виртуальных методов способом диспетчеризации на этапе выполнения. Для динамических методов компилятор вместо таблицы виртуальных методов (ТВМ) строит таблицу динамических методов (ТДМ). Применение ТДМ уменьшает размер памяти, используемой прикладной программой при работе с объектами. Однако программа при этом будет работать медленнее. Во всех других отношениях динамические методы считаются эквивалентными виртуальным.

Синтаксически, в отличие от виртуальных методов, для динамических методов в заголовке дополнительно указывается индекс динамического метода, который располагается непосредственно за ключевым словом Virtual. Индекс динамического метода должен быть целочисленной константой в диапазоне от 1 до 656535 и, кроме того, не должен повторяться среди индексов других динамических методов, которые описаны в данном объектном типе и/или его родительских типах.

Пример:

Procedure Move (C1:char,x,y:integer )virtual77

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

Особо подчеркнем, что не следует путать два понятия: динамические методы и динамические объекты. Динамические методы могут присутствовать как в динамических, так и в статических объектах.

2.6. Деструкторы

Деструктор –это так же, как и конструктор, специальный вид метода, который по-другому еще называют «сборщиком мусора».

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

Аналогично конструкторам, для которых в каждом типе рекомендуется использовать одинаковый идентификатор Init, для всех деструкторов рекомендуется использовать имя Done. Деструкторы могут быть как статистическими, так и виртуальными, и их разрешается наследовать. Поскольку для различных типов объектов чаще всего требуются различные методы освобождения памяти, то рекомендуется всегда объявлять деструкторы виртуальными, благодаря чему, для каждого типа объекта будет выполнен правильный деструктор.

Пример деструктора

Destructor Done;

begin

CloseGraph;

end;

Для освобождения динамической памяти можно использовать процедуру Freemem.

FREEMEM(P,SIZE);

Здесь, P – нетипизированный указатель, SIZE –размер в байтах освобождаемой части кучи.

Использование процедур GETMEM-FREEMEM, как и вся работа с динамической памятью, требует особой осторожности и тщательного соблюдения простого правила: освобождать нужно ровно столько памяти, сколько ее было зарезервировано, и именно с того адреса, с которого она была зарезервирована.

Рассмотрим наследование, работу конструктора и деструктора на примере, приведенном выше.

Program DemoObgectStaya;

Uses Graph,CRT;

Type

Mother = object;

k,x,y,xa,ya,bx,by,ax,ay:integer;

vver,pole,vnis:Pointer;

Mize,Size,Lize,ax1,ay1:integer;

ch:char;

Constructor init;

Procedure Draw;

Procedure Mahi; Virtual;

Procedure Polet; Virtual;

Destructor Done;

end;

Doter = object(Mother)

Constructor initD;

Procedure DrawMin;

end;

Constructor Mother init;

begin

xa;=100;

ya:=100;

bx:=ax;

by:=ay;

ax1:=ax;

ax1:=ax;

end;

Constructor Doter.initD;

begin

k:=3;

xa;=100;

ya:=100;

ax:=ax1;

ay:=ay1;

bx:=ax;

by:=ay;

end;

Destructor Mother.Done;

begin

FreeMem(Vver,Size);

FreeMem(Vniz,Lize);

end;

Procedure Mother.Draw;

begin

Mother.init;

SetColor(14);

SetFillStyle(1,14);

FillEllipse(xa,ya,10,10);

Line(xa-10,ya,xa-30,ya);

Line(xa+10,ya,xa+30,ya);

Line(xa-30,ya,xa-50,ya-20);

Line(xa+30,ya,xa+50,ya-20);

Size:=ImageSize(xa-50,ya-20,xa+50,ya+20);

GetMem(vver,size);

GetImage(xa-50,ya-20,xa+50,ya+20,vver^);

ClearDevice

FillEllipse(xa,ya,10,10);

Line(xa-10,ya,xa-30,ya);

Line(xa-10,ya,xa+30,ya);

Line(xa-30,ya,xa-50,ya+20);

Line(xa+30,ya,xa+50,ya+20);

Lize:=ImageSize(xa-50,ya-20,xa+50,ya+20);

GetMem(vniz,lize);

GetImage(xa-50,ya-20,xa+50,ya+20,vniz^);

ClearDevice:

end;

Procedure Mother.Mahi(bx,by:integer);

begin

Mize:=ImageSize(bx,by,bx+100,by+40);

GetMem(pole,mize);

GetImage(bx,by,bx+100,by+40,pole^);

PutImage(bx,by,vver^,1);

delay(70);

PutImage(bx,by,pole^,0);

end;

Procedure Mother.Polet(ax,ay:integer);

Begin

ax:=ax1;

ay:=ay1;

repeat

if KeyPressed then

begin

ch:=ReadKey;

case ch of

#77:ax:=ax+10;

#75:ax:=ax-10;

#80:ay:=ay+10;

#72:ay:=ay-10;

end;

Mother.init;

Mahi;

end;

else

begin

Mother.init;

Mahi;

end;

until ch=#32;

Mother.init;

ax1:=ax;

ay1:=ay;

end;

Procedure Doter.DrawMin;

begin

SetColor(14);

SetFillStyle(1,14);

FillEllipse(xa,ya,round(10/k),round(10/k));

Line(xa- round(10/k),ya,xa- round(30/k),ya);

Line(xa+ round(10/k),ya,xa+ round(30/k),ya);

Line(xa- round(30/k),ya,xa- round(50/k),ya- round(20/k));

Line(xa+round(30/k),ya,xa+round(50/k),ya- round(20/k));

Size:=ImageSize(xa-round(50/k),ya-round(20/k),xa+round (50/k),ya+round(20/k));

GetMem(vver,size);

GetImage(xa-round(50/k),ya-round(20/k),xa+round(50/k), ya+ round(20/k),vver^);

ClearDevice

FillEllipse(xa,ya, round(10/k), round(10/k));

Line(xa- round(10/k),ya,xa- round(30/k),ya);

Line(xa- round(10/k),ya,xa+ round(30/k),ya);

Line(xa-round(30/k),ya,xa-round(50/k),ya+round(20/k));

Line(xa+round(30/k),ya,xa+round(50/k),ya+round(20/k));

Lize:=ImageSize(xa-round(50/k),ya-round(20/k),xa+ round (50/k),ya+ round(20/k));

GetMem(vniz,lize);

GetImage(xa-round(50/k),ya-round(20/k),xa+round(50/k), ya+ round(20/k),vniz^);

ClearDevice:

end;

Var GrDriver, GrMode,alx,aly:integer;

gol:mother;vorob:Doter;

Begin

GrDriver:=Detect;

InitGraph(GrDriver, GrMode, 'C: |Bp|BGI');

readln;

Gol.init;

Gol.Draw;

Gol.Polet;

Gol.Done;

Vorob.initD;

vorob.drawmin;

Vorob.initD;

vorob.Polet;

vorob.Done;

CloseGraph;

End.