Введение в объектно-ориентированное программирование на языке Object Pascal. Соколов Е.В. - 71 стр.

UptoLike

Составители: 

71
else
if VMT.Ancestor<>nil
then result:=VMT.Ancestor.TypeNameIs(VMT.Ancestor, TypeName)
else result:=false;
{ Если значение параметра TypeName совпадает с именем, указанным
в VMT, то результат - "истина". В противном случае он определяется
версией той же функции из типа-предка, если таковой существует. }
end;
function Create: PNumber;
begin
New(result);
result.VMT:=@TypeNumber; // инициализируем ссылку на VMT
end;
procedure Destroy(var n: PNumber);
begin Dispose(n); end;
initialization
TypeNumber.TypeName:='Number';
TypeNumber.Ancestor:=nil; // у типа Number нет предка
TypeNumber.TypeNameIs:=TypeNameIs;
TypeNumber.Create:=Create;
TypeNumber.Destroy:=Destroy;
end.
Поскольку Number абстрактный тип, его объект не содержит
ничего, кроме адреса таблицы виртуальных методов , хранящейся в от-
крытой переменной TypeNumber. Заполнение ее полей происходит один
раз в процессе инициализации модуля, так что мы получаем некоторый
выигрыш во времени при создании объ ектов .
Заметим , что помимо процедурных указателей переменная Type-
Number включает два поля: TypeName (имя типа) и Ancestor (ссылка на
VMT типа-пред ка); о них и о функции TypeNameIs мы поговорим ниже.
Кроме того, функция-кон структор Create теперь также является вирту-
альной .
При использовании новой версии типа Number вызов методов
осуществляется посредством выражений вида:
n3:=n1.VMT.Plus(n1,n2);
n1.VMT.Add(n1,n2);
  else
    if VMT.Ancestor<>nil
      then result:=VMT.Ancestor.TypeNameIs(VMT.Ancestor, TypeName)
      else result:=false;

{ Если значение параметра TypeName совпадает с именем, указанным
  в VMT, то результат - "истина". В противном случае он определяется
  версией той же функции из типа-предка, если таковой существует. }

end;

function Create: PNumber;
begin
  New(result);
  result.VMT:=@TypeNumber; // инициализируем ссылку на VMT
end;

procedure Destroy(var n: PNumber);
begin Dispose(n); end;

initialization

TypeNumber.TypeName:='Number';
TypeNumber.Ancestor:=nil;          // у типа Number нет предка
TypeNumber.TypeNameIs:=TypeNameIs;
TypeNumber.Create:=Create;
TypeNumber.Destroy:=Destroy;

end.


        Пос кол ь ку Number — абс т ракт ны й т ип, его объект не с од ержит
ничего, кром е ад рес а т абл ицы в ирт уал ь ны хм етод ов , хранящейс я в от -
кры той перем енной TypeNumber. Запол нение ее пол ей проис ход ит од ин
раз в процес с е инициал из ации м од ул я, т ак чтом ы пол учаем некоторы й
в ы игры ш в ов рем ени при с оз д ании объектов .
        Зам ет им , что пом им о процед урны хуказ ат ел ей перем енная Type-
Number в кл ючает д в а пол я: TypeName (им я т ипа) и Ancestor (с с ы л ка на
VMT т ипа-пред ка); онихи офункции TypeNameIs м ы погов орим ниже.
Кром е того, функция-конс т руктор Create т еперь т акже яв л яет с я в ирту-
ал ь ной.
        При ис пол ь з ов ании нов ой в ерс ии т ипа Number в ы з ов м етод ов
ос ущес т в л яет с я пос ред с т в ом в ы ражений в ид а:
                          n3:=n1.VMT.Plus(n1,n2);
                             n1.VMT.Add(n1,n2);



                                      71