Obiekt zawiera wpisy dla wszystkich swoich pól oraz dodatkowe miejsce na wskaźnik do tabeli metod wirtualnych. VMT posiada więcej niż wskaźniki wirtualnej metody. Wyjaśniam more about the VMT na mojej stronie internetowej, w tym diagram.
Podobno Delphi 2009 wprowadza inne ukryte pole oprócz wskaźnika VMT do przechowywania monitora synchronizacji. Można określić, czy jest on dodawany na początku lub na końcu klasy z jakiegoś prostego kodu:
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.
Jeśli drukuje wartość 4, a następnie w polu monitor musi być na końcu obiektu, ponieważ 4 uwzględnia tylko wielkość wskaźnika VMT. Jeśli wypisze wartość 8, pole monitora musi znajdować się na początku, obok wskaźnika VMT.
Oczekuję, że znajdziesz monitor na starcie. W przeciwnym razie oznacza to, że układ obiektu potomnego nie jest po prostu układem obiektu bazowego z dołączonymi wszystkimi nowymi polami. Oznaczałoby to przesunięcie pola monitora w zależności od typu obiektu, co powoduje, że implementacja jest bardziej skomplikowana.
Gdy klasa implementuje interfejs, układ obiektu zawiera więcej ukrytych pól. Pola zawierają wskaźniki do wartości odniesienia dla interfejsu obiektu. W przypadku odwołania do obiektu o wartości IUnknown
wskazany przez niego wskaźnik nie jest tym samym, co wskaźnik do pola VMT obiektu, czyli tym, co mamy w przypadku zwykłego odwołania do obiektu. Wartość wskaźnika IUnknown
będzie adresem ukrytego pola. Napisałem more about the layout of classes that implement interfaces.
To dokładnie to samo. Punkt odniesienia klasy TClass wskazuje na jej VMT. Więc to są te same 4 bajty. Jakie są pozostałe 4? –
(Warto zauważyć, że ta książka została napisana 9 lat temu.Może wtedy było tylko jedno ukryte pole. Wygląda na to, że są dwie.) –
Istnieje również monitor synchronizacji w D2009. Zaktualizuję. –