Какие данные содержит TObject? - PullRequest
8 голосов
/ 24 марта 2009

TObject.InstanceSize возвращает 8, но TObject не объявляет никаких элементов данных. Согласно реализации TObject.ClassType, первые 4 байта могут быть объяснены как указатель на метаданные объекта TClass. Кто-нибудь знает, для чего предназначены остальные 4 байта служебных данных?

РЕДАКТИРОВАТЬ: Очевидно, это относится к D2009. В старых версиях это всего 4 байта.

Ответы [ 3 ]

12 голосов
/ 24 марта 2009

В Delphi 2009 есть возможность иметь ссылку на монитор синхронизации . См:

class function TMonitor.GetFieldAddress(AObject: TObject): PPMonitor;
class function TMonitor.GetMonitor(AObject: TObject): PMonitor;

... в System.pas

Кроме того, еще есть указатель на VMT. (Таблица виртуальных методов.) С Delphi в двух словах :

Класс TObject объявляет несколько методы и одно специальное скрытое поле хранить ссылку на объект учебный класс. Это скрытое поле указывает на таблица виртуальных методов класса (VMT). Каждый класс имеет уникальный VMT и все объекты этого класса разделяют ВМТ класса.

3 голосов
/ 25 марта 2009

Объект содержит записи для всех его полей, а также дополнительное пространство для хранения указателя на таблицу виртуальных методов. VMT содержит больше, чем просто указатели виртуальных методов. Я объясню больше о VMT на моем веб-сайте, включая диаграмму.

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

type
  TTest = class
    FField: Integer;
  end;

var
  obj: TTest;
  ObjAddr, FieldAddr: Cardinal;
begin
  Assert(TTest.InstanceSize = 12);
  obj := TTest.Create;
  ObjAddr := Cardinal(obj);
  FieldAddr := Cardinal(@(obj.FField));
  writeln(FieldAddr - ObjAddr);
end.

Если он печатает значение 4, то поле монитора должно быть в конце объекта, потому что 4 учитывает только размер указателя VMT. Если он печатает значение 8, то поле монитора должно быть в начале, рядом с указателем VMT.

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

Когда класс реализует интерфейс, структура объекта включает в себя больше скрытых полей. Поля содержат указатели на значение ссылки на интерфейс объекта. Когда у вас есть ссылка IUnknown на объект, указатель, который он содержит, не совпадает с указателем на поле VMT объекта, которое вы имеете при использовании обычной ссылки на объект. Значение указателя IUnknown будет адресом скрытого поля. Я написал подробнее о компоновке классов, которые реализуют интерфейсы .

0 голосов
/ 25 марта 2009

На всякий случай, если кому-то интересно, почему ответ Крейга Стунца был принят, см. Его последний комментарий к этому ответу:

Похоже, что было добавлено в D2009: http://blogs.embarcadero.com/abauer/2008/02/19/38856 Смотрите ссылки в этом сообщении для получения полной информации.

Ссылка больше не доступна, но у wayback-machine она есть:

https://web.archive.org/web/20160409224957/blogs.embarcadero.com/abauer/2008/02/19/38856

...