Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Механизм вызова виртуальных методов



Работа виртуальных методов основана на косвенном вызове подпрограмм. При косвенном вызове команда вызова подпрограммы оперирует не адресом подпрограммы, а адресом места в памяти, где хранится адрес подпрограммы. Вы уже сталкивались с косвенным вызовом при использовании процедурных переменных. Процедурная переменная и была тем местом в памяти, где хранился адрес вызываемой подпрограммы. Для каждого виртуального метода тоже создается процедурная переменная, но ее наличие и использование скрыто от программиста.

Все процедурные переменные с адресами виртуальных методов пронумерованы и хранятся в таблице, называемой таблицей виртуальных методов (VMT — от англ. Virtual Method Table). Такая таблица создается одна для каждого класса объектов, и все объекты этого класса хранят на нее ссылку.

Структуру объекта в оперативной памяти поясняет рисунок 3.3:


Рисунок 3.3. Структура объекта TTextReader в оперативной памяти

Вызов виртуального метода осуществляется следующим образом:

1. Через объектную переменную выполняется обращение к занятому объектом блоку памяти;

2. Далее из этого блока извлекается адрес таблицы виртуальных методов (он записан в четырех первых байтах);

3. На основании порядкового номера виртуального метода извлекается адрес соответствующей подпрограммы;

4. Вызывается код, находящийся по этому адресу.

Покажем, как можно реализовать косвенный вызов виртуального метода ParseLine (он имеет нулевой номер в таблице виртуальных методов) обычными средствами процедурного программирования:

type TVMT = array[0..9999] of Pointer; TParseLineFunc = function (Self: TTextReader; const Line: string): Integer; var Reader: TTextReader; // объектная переменна ObjectDataPtr: Pointer; // указатель на занимаемый объектом блок памяти VMTPtr: ^TVMT; // указатель на таблицу виртуальных методов MethodPtr: Pointer; // указатель на метод begin ... ObjectDataPtr: = Pointer(Reader); // 1) обращение к данным объекта VMTPtr: = Pointer(ObjectDataPtr^); // 2) извлечение адреса VMT MethodPtr: = VMTPtr^[0]; // 3) извлечение адреса метода из VMT TParseLineFunc(MethodPtr)(Reader, S); // 4) вызов метода ... end.

Поддержка механизма вызова виртуальных методов на уровне языка Delphi избавляет программиста от всей этой сложности.

Абстрактные виртуальные методы

При построении иерархии классов часто возникает ситуация, когда работа виртуального метода в базовом классе не известна и наполняется содержанием только в наследниках. Так случилось, например, с методом ParseLine, тело которого в классе TTextReader объявлено пустым. Конечно, тело метода всегда можно сделать пустым или почти пустым (так мы и поступили), но лучше воспользоваться директивой abstract:

type TTextReader = class ... function ParseLine(const Line: string): Integer; virtual; abstract; ... end;

Директива abstract записывается после слова virtual и исключает необходимость написания кода виртуального метода для данного класса. Такой метод называется абстрактным, т.е. подразумевает логическое действие, а не конкретный способ его реализации. Абстрактные виртуальные методы часто используются при создании классов-полуфабрикатов. Свою реализацию такие методы получают в законченных наследниках.

Динамические методы

Разновидностью виртуальных методов являются так называемые динамические методы. При их объявлении вместо ключевого слова virtual записывается ключевое слово dynamic, например:

type TTextReader = class ... function ParseLine(const Line: string): Integer; dynamic; abstract; ... end;

В наследниках динамические методы перекрываются так же, как и виртуальные — с помощью зарезервированного слова override.

По смыслу динамические и виртуальные методы идентичны. Различие состоит только в механизме их вызова. Методы, объявленные с директивой virtual, вызываются максимально быстро, но платой за это является большой размер системных таблиц, с помощью которых определяются их адреса. Размер этих таблиц начинает сказываться с увеличением числа классов в иерархии. Методы, объявленные с директивой dynamic вызываются несколько дольше, но при этом таблицы с адресами методов имеют более компактный вид, что способствует экономии памяти. Таким образом, программисту предоставляются два способа оптимизации объектов: по скорости работы ( virtual ) или по объему памяти ( dynamic ).

Методы обработки сообщений

Специализированной формой динамических методов являются методы обработки сообщений. Они объявляются с помощью ключевого слова message, за которым следует целочисленная константа — номер сообщения. Следующий пример взят из исходных текстов библиотеки VCL:

type TWidgetControl = class(TControl) ... procedure CMKeyDown(var Msg: TCMKeyDown); message CM_KEYDOWN; ... end;

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

Методы обработки сообщений применяются внутри библиотеки VCL для обработки команд пользовательского интерфейса и редко нужны при написании прикладных программ.


Поделиться:



Популярное:

  1. Агенты, стадии и механизмы политической социализации
  2. Анатомо-физиологические механизмы речи
  3. Анатомо-физиологические механизмы речи.
  4. Антивитамины фолиевой кислоты. Механизм действия сульфаниламидных препаратов.
  5. Антиген на клетке Антитело приходит к клетке. Это механизм таких аллергических реакций по кумбсу и джеллу. Цитотоксические
  6. Антитело на клетке антиген приходит к клетке. Это механизм таких аллергических реакций по кумбсу и джеллу. Анафилактические
  7. Базовая модель в контексте формализованной схемы моделирования хозяйственного механизма
  8. Биологические особенности опухолей, механизм их развития
  9. Биохимические механизмы мышечного сокращения и расслабления. Роль градиента одновалентных ионов и ионов кальция в регуляции мышечного сокращения и расслабления.
  10. Виды и функции управления. Хозяйственный механизм
  11. Виды кулачковых механизмов. Кулачковые механизмы
  12. Виды управления,социальное управление, механизм управления.


Последнее изменение этой страницы: 2016-07-14; Просмотров: 942; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.009 с.)
Главная | Случайная страница | Обратная связь