![](/img/trans.png)
[英]What guarantees does TObject provide about the clearing of interface fields at object destruction time?
[英]What data does a TObject contain?
TObject.InstanceSize 返回 8,但 TObject 沒有聲明任何數據成員。 根據 TObject.ClassType 的實現,前 4 個字節可以解釋為指向對象的 TClass 元數據的指針。 有人知道其他 4 個字節的開銷是做什么用的嗎?
編輯:顯然這是特定於 D2009。 在舊版本中,它只有 4 個字節。
在 Delphi 2009 中, 可以引用同步監視器。 看:
class function TMonitor.GetFieldAddress(AObject: TObject): PPMonitor;
class function TMonitor.GetMonitor(AObject: TObject): PMonitor;
...在 System.pas
此外,還有一個指向 VMT 的指針。 (虛擬方法表。)簡而言之,來自 Delphi :
TObject class 聲明了幾種方法和一個特殊的隱藏字段來存儲對對象 class 的引用。 此隱藏字段指向類的虛擬方法表 (VMT)。 每個 class 都有一個唯一的 VMT,並且該 class 的所有對象共享該類的 VMT。
object 包含其所有字段的條目,以及用於保存指向虛擬方法表的指針的額外空間。 VMT 不僅僅包含虛擬方法指針。 我在我的 Web 站點上解釋了更多關於 VMT的信息,包括一個圖表。
顯然,Delphi 2009 除了用於保存同步監視器的 VMT 指針外,還引入了另一個隱藏字段。 您可以通過一些簡單的代碼來確定它是添加在 class 的開頭還是結尾:
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,則監視字段必須位於 object 的末尾,因為 4 僅說明 VMT 指針的大小。 如果它打印值 8,則監視器字段必須位於開頭,與 VMT 指針相鄰。
我希望你會在一開始就找到監視器。 否則,這意味着后代 object 的布局不僅僅是附加了所有新字段的基本 object 的布局。 這意味着監視字段的偏移量取決於 object 的運行時類型,這使得實現更加復雜。
當 class 實現接口時,object 布局包含更多隱藏字段。 這些字段包含指向對象的接口引用值的指針。 當你有一個對 object 的IUnknown
引用時,它持有的指針與指向對象的 VMT 字段的指針不同,這與普通的 object 引用相同。 IUnknown
指針值將是隱藏字段的地址。 我已經寫了更多關於實現接口的類的布局。
萬一有人想知道為什么 Craig Stuntz 的回答被接受了,請參閱他對該回答的最后評論:
看起來像是在 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.