- •1. Библиотечный модуль Graf
- •1.1. Характеристика графических режимов работы адаптера
- •1.2. Основные процедуры и функции графического модуля
- •Процедура CloseGraph
- •1.3. Изображение линий и точек
- •1.4. Изображение многоугольников
- •1.5. Изображение дуг, окружностей, эллипсов
- •1.6. Краски, Палитры, Заполнения
- •Процедура GetDefaultPalette
- •Процедура SetFillStyle
- •1.7. Вывод текста
- •Задает выравнивание выводимого по отношению к текущему положению указателя или к заданным координатам. Заголовок:
- •Процедура SetUserCharSize
- •Функция TextWidth
- •Функция TextHeight
- •1.8. Координаты. Окна. Страницы
- •Функции GetX и GetY
- •Процедура SetViewPort
- •Процедура SetActivePage
- •1.9. Сохранение и выдача изображений
- •2. Объектно-ориентированное программирование
- •2.1. Основные принципы ооп
- •2.2. Создание объектов
- •2.3. Наследование. Правила наследования
- •2.4. Виртуальные и динамические методы
- •2.5. Отличие виртуальных и динамических методов
- •2.6. Деструкторы
- •Список заданий выпускной квалификационной работы
- •Литература
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.
