IMPLEMENTATION

INTERFACE

uses CRT,Fbyte;

var pred_attr:byte;{предыдущий атрибут текст.режима}

wmin,wmax:word;{координаты предыдущего окна}

msgK1,msgK2:string;{формулы кодирования}

K1,K2:byte;{контрольные байты кода}

procedure save_state;{сохранить состояние}

procedure set_state;{восстановить состояние}

 

type Tsymb = object {объект - Символ }

c:char; {символ вывода}

col:byte; {цвет символа}

Xc,Yc:byte;{координаты символа}

procedure put_sym(ch:char;color:byte);{вывести символ}

procedure put_bsym(ch:char;color:byte);{вывести байт-символ}

procedure change_c(color:byte);{изменить цвет байт-символа}

procedure gen_sym(color:byte);{сгенерировать байт-символ}

end {Tsymb};

type Tstr_symb =object(Tsymb) {объект - Строка символов }

procedure put_str(st:string;color:byte;t:word);{вывести строку}

procedure put_bstr(st:string;color:byte;t:word);{вывести байты}

procedure codK1(st:string);{вычислить контр.байт K1}

procedure codK2(st:string);{вычислить контр.байт K2}

end {Tstr_symb};

procedure save_state;

begin pred_attr:=TextAttr; wmin:=WindMin;wmax:=WindMax;

end {save_state};

procedure set_state;

begin WindMax:=wmax;Windmin:=wmin;TextAttr:=pred_attr

end{set_state};

procedure Tsymb.put_sym(ch:char;color:byte);

begin Xc:=whereX;Yc:=whereY;save_state;c:=ch;col:=color;

window(Xc,Yc,Xc+2,Yc);TextBackground(col);ClrScr;

write(ch);set_state;GotoXY(Xc+3,Yc)

end {put_sym};

procedure Tsymb.put_bsym(ch:char;color:byte);

var j:byte;s3:string;

beginXc:=whereX;Yc:=whereY;save_state;c:=ch;col:=color;

window(Xc,Yc,Xc+2,Yc+2); TextBackground(col);ClrScr;for j:=1 to 3 do

begin s3:=b_str3(ord(ch));write(s3[j]);GotoXY(whereX-1,whereY+1);

end;set_state;GotoXY(Xc+3,Yc);Xc:=whereX;Yc:=whereY;

end {put_bsym};

procedure Tsymb.change_c(color:byte);

begin GotoXY(Xc-3,Yc);put_bsym(c,color)

end {change_c};

procedure Tsymb.gen_sym(color:byte);

begin randomize;c:=chr(random(256));put_bsym(c,color)

end {gen_sym};

procedure Tstr_symb.put_str(st:string;color:byte;t:word);

var j:byte;

begin for j:=1 to length(st) do begin put_sym(st[j],color);delay(t) end

end {put_str};

procedure Tstr_symb.put_bstr(st:string;color:byte;t:word);

var j:byte;

begin for j:=1 to length(st) do begin put_bsym(st[j],color);delay(t) end

end {put_bstr};

 

procedure Tstr_symb.codK1(st:string);

var j:byte;s:string;

begin K1:=0;j:=1;msgK1:='C0';

repeat K1:=fplus(K1,ord(st[j]));if (j<10)and(j<length(st)) then

begin str(j,s);msgK1:=msgK1+'+C'+s end;

if j=10 then msgK1:=msgK1+'+..';inc(j)

until j=length(st);K1:=fplus(K1,ord(st[j]));msgK1:=msgK1+'=K1';

while length(msgK1)<=(3*(length(st))+1) do

insert('.',msgK1,length(msgK1)-2);msgK1:=msgK1+' '

end{codK1};

procedure Tstr_symb.codK2(st:string);

var j:byte;

begin K2:=fmult(ord(st[1]),2);j:=2;

repeat K2:=fmult(fplus(K2,ord(st[j])),2);inc(j)

until j=length(st);K2:=fplus(K2,ord(st[j]));msgK2:='(..(C0*2+C1)*2+С2)*2+..)= K2';

while length(msgK2)<length(msgK1) doinsert('.',msgK2,22)

end{codK2};

END{cod_Hem}.

 

5. Понятие о динамических объектах.

Объектные переменные совершенно подобны переменным других типов Турбо Паскаля. Как мы уже отмечали, для них допустим оператор присваивания и обращение к полям и методам по составным именам (как для записей). Экземпляры объектов можно размещать и в динамической памяти. Экземпляры объектов, размещаемые в динамической памяти, называются динамическими объектами.

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

type pLine = ^Line; {указатель на объект типа Line }

var pL1:pLine; {динамический объект типа pLine}

Динамические объекты чрезвычайно полезны для задач моделирования, управления, проектирования. Библиотеки объектов в большинстве своём содержат динамические объекты, как например Turbo Vision -библиотека объектов интерфейса.

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

 

6. Расширенное использование процедуры new.

При работе с динамическими объектами процедуру new (выделения хип-памяти под типизированные указатели) можно использовать с расширенными возможностями:

- в ней допускается второй параметр, в котором можно указывать обращение к конструктору для инициализации динамического объекта;

- процедуру new можно вызывать как функцию, возвращающую значение типа указатель, которое указывает на динамически размещаемый объект. Первым параметром функции new (в отличие от процедуры new) должен быть тип размещаемого объекта, а вторым параметром может быть (как и в процедуре new) имя конструктора.

Такие расширенные средства позволяют одновременно, и зарезервировать хип-память для динамического объекта и разместить в ней некоторое (начальное) значение (с помощью конструктора). В теле конструктора допускается создание нового динамического объекта и так далее. В такой ситуации (использования нескольких уровней вложенности) проблемой может стать нехватка распределяемой хип-памяти. При нехватке хип-памяти необходимо ликвидировать всю цепочку размещенных объектов. Эту операцию может выполнить стандартная процедура fall, которую можно вызывать только из конструктора и которая освобождает выделенную память, возвращая значение указателя nil. Примеры расширенного использования new:

 

var pL1:^Line; {динамический объект типа Line}

. . . .. .. .

new(pL1,Init); {Init - конструктор для инициализации объекта pL1}

. . .. . . .. .

pL1:= new(Line, Init); {инициализация pL1 с помощью функции new}

 

7. Освобождение хип-памяти от динамических объектов.

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

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

Для удобства использования деструктора предусмотрено расширенное использование стандартной процедуры dispose - освобождения хип-памяти. В этой процедуре разрешено применять кроме обычного параметра (переменной типа указатель) также второй параметр - имя деструктора объекта. Например:

type Line = object (point);

. . . . . .

constructor Init;

destructor Done;

end {Line}.

new(pL1, Init); {Создание динамического объекта pL1}

. . . . . .

dispose(pL1, Done); {Удаление динамического объекта pL1}