TURBO PASCAL

Новости

Программы   

Turbo Pascal 

Игры

Документация   

Странности

FAQ

Ссылки

Форум

Гостевая книга

Рассылка

Благодарности

Об авторе

 

 

Виртуальные методы 

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

             Ниже приведены знакомые вам объекты из примера платежной ве-
        домости, должным образом виртуализированные:

             tyрe
              PEmрloyee = ^TEmployee;
              TEmployee = object
               Name, Title: string[25];
               Rate: Real;
               constructor Init (AName, ATitle: String; ARate: Real);
               function GetPayAmount : Real; virtual;
               function GetName : String;
               function GetTitle : String;
               function GetRate : Real;
               рrocedure Show; virtual;
             end;

             PHourly = ^THourly;
             THourly = object(TEmployee);
               Time: Integer;
               constructor Init (AName, ATitle: String; ARate: Real;
               Time: Integer);
               function GetPayAmount : Real; virtual;
               function GetTime : Integer;
             end;

             PSalaried = ^TSalaried;
             TSalaried = object(TEmployee);
               function GetPayAmount : Real; virtual;
             end;

             PCommissioned = ^TCommissioned;
             TCommissioned = object(Salaried);
               Commission : Real;
               SalesAmount : Real;
               constructor Init (AName, ATitle: String;
                   ARate, ACommission, ASalesAmount: Real);
               function GetPayAmount : Real; virtual;
             end;

             А ниже  приводится пример для насекомых,  дополненный вирту-
        альными методами.

             tyрe
              TWinged = object(Insect)
                 constructor Init (AX, AY : Integer)
                 рrocedure Show; virtual;
                 рrocedure Hide; virtual;
              end;


             tyрe
              TBee = object(TWinged)
                 constructor Init (AX, AY : Integer)
                 рrocedure Show; virtual;
                 рrocedure Hide; virtual;
              end;

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

             Отметьте также  новое  зарезервированное  слово  constructor
        (конструктор),  заменившее зарезервированное слово рrocedure  для
        TWinged.Init и TBee.Init.  Конструктор является специальным типом
        процедуры,  которая выполняет некоторую установочную  работу  для
        механизма виртуальных методов. Более того, конструктор должен вы-
        зываться перед вызовом любого виртуального метода.  Вызов  вирту-
        ального  метода  без  предварительного  вызова конструктора может
        привести к блокированию системы, а у компилятора нет способа про-
        верить порядок вызова методов.

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

             Предупреждение: Конструктор должен вызываться перед  вызовом
        любого другого виртуального метода. Вызов виртуального метода без
        предыдущего обращения к  конструктору  может  вызвать  блокировку
        системы,  и компилятор не сможет проверить порядок, в котором вы-
        зываются методы.

                   Примечание: Для конструкторов  объекта  мы  предлагает
              использовать идентификатор Init.

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

             var
               FBee, GBee: Bee;    { создать два экземпляра Bee }
             begin
               FBee.Init(5, 9)     { вызов конструктора для FBee }
               GBee := FBee;       { Gbee недопустим! }
             end;
             Что же именно создает конструктор? Каждый тип объекта содер-
        жит нечто,  называемое таблицей виртуального метода (ТВМ) в  сег-
        менте данных. ТВМ содержит размер типа объекта и для каждого вир-
        туального метода указатель  на  код,  выполняющий  данный  метод.
        Конструктор  устанавливает связь между вызывающей его реализацией
        объекта и ТВМ типа объекта.

             Важно помнить,  что имеется только одна ТВМ для каждого типа
        объекта. Отдельные экземпляры типа объекта (т.е. переменные этого
        типа) содержат только соединение с ТВМ, но не саму ТВМ. Конструк-
        тор устанавливает значение этого соединения в ТВМ.  Именно благо-
        даря этому вы нигде не можете запустить выполнение перед  вызовом
        конструктора.


Содержание

На первую страницу

Rambler's Top100 Rambler's Top100
PROext: Top 1000

(с)Все права защищены

По всем интересующим вопросам прошу писать на электронный адрес

Hosted by uCoz