TURBO PASCAL |
Новости
|
Таблица виртуальных методовКаждый объектный тип, содержащий или наследующий виртуальные методы, конструкторы или деструкторы, имеет связанную с ним таб- лицу виртуальных методов, в которой запоминается инициализируемая часть сегмента данных программы. Для каждого объектного типа (но не для каждого экземпляра) имеется только одна таблица виртуаль- ных методов, однако два различных объектных типа никогда не раз- деляют одну таблицу виртуальных методов, независимо от того, нас- колько эти типы идентичны. Таблицы виртуальных методов создаются автоматически компилятором, и программа никогда не манипулирует ими непосредственно. Аналогично, указатели на таблицы виртуальных методов автоматически запоминаются в реализациях объектных типов с помощью конструкторов программа никогда не работает с этими указателями непосредственно. Первое слово таблицы виртуальных методов содержит размер экземпляров соответствующего объектного типа. Эта информация ис- пользуется конструкторами и деструкторами для определения того, сколько байт выделяется или освобождается при использовании рас- ширенного синтаксиса стандартных процедур New и Dispose. Второе слово таблицы виртуальных методов содержит отрица- B.Pascal 7 & Objects/LR - 379 - тельный размер экземпляров соответствующего объектного типа эта информация используется ратификационным (т.е. подтверждающим действительность) механизмом вызова виртуального метода для выяв- ления инициализируемых объектов (экземпляров, для которых должен выполняться конструктор) и для проверки согласованности таблицы виртуальных методов. Когда разрешена ратификация виртуального вы- зова (с помощью директивы {$R+} компилятора, которая расширена и включает в себя проверку виртуальных методов), компилятор генери- рует вызов программы ратификации таблицы виртуальных методов пе- ред каждым вызовом виртуального метода. Программа ратификации таблицы виртуальных методов проверяет, что первое слово таблицы виртуальных методов не равно нулю и что сумма первого и второго слов равна нулю. Если любая из проверок неудачна, то генерируется ошибка 210 исполняющей системы Borland Pascal. Разрешение проверок границ диапазонов и проверок вызовов виртуальных методов замедляет выполнение программы и делает ее несколько больше, поэтому используйте {$R+} только во время от- ладки и переключите эту директиву в состояние {$R-} в окончатель- ной версии программы. Наконец, начиная со смещения 4 таблицы виртуальных методов следует список 32-разрядных указателей методов, один указатель на каждый виртуальный метод в порядке их описаний. Каждая позиция содержит адрес точки входа соответствующего виртуального метода. B.Pascal 7 & Objects/LR - 380 - На Рис. 21.9 показано размещение таблиц виртуальных методов типов Point и Circle (тип Location не имеет таблицы виртуальных методов, т.к. не содержит в себе виртуальных методов, конструкто- ров и деструкторов): каждый маленький прямоугольник соответствует одному слову памяти, а каждый большой прямоугольник - двум словам памяти. Point VMT Circle VMT ┌───────────────┐ ┌────────────────┐ │ 8 │ │ 8 │ ├───────────────┤ ├────────────────┤ │ -8 │ │ -8 │ ├───────────────┤ ├────────────────┤ │ 0 │ │ 0 │ ├───────────────┤ ├────────────────┤ │ 0 │ │ 0 │ ├───────────────┤ ├────────────────┤ │ │ │ │ │ @TPoint.Done │ │ @TPoint.Done │ │ │ │ │ ├───────────────┤ ├────────────────┤ │ │ │ │ │ @TPoint.Show │ │ @TCircle.Show │ │ │ │ │ ├───────────────┤ ├────────────────┤ │ │ │ │ │ @TPoint.Hide │ │ @TCircle.Hide │ │ │ │ │ ├───────────────┤ ├────────────────┤ │ │ │ │ │ @TPoint.MoveTo│ │ @TPoint.MoveTo │ │ │ │ │ └───────────────┘ ├────────────────┤ │ │ │ @TCircle.Fill │ │ │ └────────────────┘ Рис. 21.9 Схемы таблиц виртуальных методов для TPoint и TCircle. Обратите внимание на то, как TCircle наследует методы Done и MoveTo типа TPoint и как он переопределяет Show и Hide. Как уже упоминалось, конструкторы объектных типов содержат специальный код, который запоминает смещение таблицы виртуальных методов объектного типа в инициализируемых экземплярах. Например, если имеется экземпляр P типа TPoint и экземпляр C типа TCircle, то вызов P.Init будет автоматически записывать смещение таблицы виртуальных методов типа TPoint в поле таблицы виртуальных мето- дов экземпляра P, а вызов C.Init точно так же запишет смещение таблицы виртуальных методов типа TCircle в поле таблицы виртуаль- B.Pascal 7 & Objects/LR - 381 - ных методов экземпляра C. Эта автоматическая инициализация явля- ется частью кода входа конструктора, поэтому если управление пе- редается в начало операторной секции, то поле Self таблицы вирту- альных методов также будет установлено. Таким образом, при воз- никновении необходимости, конструктор может выполнить вызов вир- туального метода. |
(с)Все права защищены По всем интересующим вопросам прошу писать на электронный адрес |