Вызовы виртуальных методов
Для вызова виртуального метода компилятор генерирует код, который выбирает адрес таблицы виртуальных методов из поля табли- цы виртуальных методов объекта, и затем вызывает метод, используя связанную с ним точку входа. Например, если дана переменная PP типа Point, то вызов PP^.Show будет генерировать следующий код:
les di, PP ; загрузить PP в ES:DI push es ; передать, как параметр Self push di mov di, es:[di + 6] ; извлечь смещение ТВМ из поля ТВМ call DWORD PTR [di + 12] ; вызвать запись ТВМ для Show
Правила совместимости типов для объектных типов позволяют PP указывать на Point и на TCircle или на любых других потомков TPoint. И если вы просмотрите показанные здесь таблицы виртуаль- ных методов, то вы увидите, что для типа TPoint точка входа со смещением 12 в таблицы виртуальных методов указывает на TPoint.Show. Таким образом, в зависимости от фактического во вре- мя выполнения типа PP, инструкция CALL вызывает либо TPoint.Show, либо TCircle.Show, либо метод любого другого потомка TPoint.
Если Show является статическим методом, то для вызова PP.Show будет генерироваться следующий код:
les di, PP ; загрузить PP в ES:DI push es ; передать, как параметр Self push di call TPoint.Show ; непосредственно вызвать TPonit.Show
В данном случае не имеет значения, на что указывает PP, и код всегда будет вызывать метод TPoint.Show.