gpt4 book ai didi

delphi - New 和 Dispose 内部做什么?

转载 作者:行者123 更新时间:2023-12-03 15:05:07 31 4
gpt4 key购买 nike

我想知道调用 New 和 Dispose 时内部会发生什么。 Delphi帮助给出了合理的解释,但是如果一个人自己写New和Dispose该怎么办?两者内部调用了哪些方法还是全部都是汇编?

我不想编写自己的 New 和 Dispose。我只是对这两种方法的内部工作原理非常好奇。

最佳答案

New 执行以下操作:

  1. 通过调用 GetMem 为新对象分配内存。
  2. 初始化任何托管字段,例如字符串、接口(interface)、动态数组等。

Dispose 逆转了这一点:

  1. 最终确定托管字段。
  2. 通过调用 FreeMem 释放内存。

请注意,NewDispose 均为 intrinsic functions 。这意味着编译器对它们有额外的了解,并且能够根据相关类型改变它们的实现方式。

例如,如果类型没有托管字段,则 New 会优化为对 GetMem 的简单调用。如果类型具有托管字段,则通过调用 System._New 来实现 New,该调用执行上述步骤。

Dispose 的实现非常相似。对于非托管类型,简单调用 FreeMem,否则调用 System._Dispose

现在,System._New 的实现如下:

function _New(Size: NativeInt; TypeInfo: Pointer): Pointer;
begin
GetMem(Result, Size);
if Result <> nil then
_Initialize(Result, TypeInfo);
end;

请注意,为了简单起见,我刚刚展示了 PUREPASCAL 变体。对 GetMem 的调用非常简单。对 System._Initialize 的调用涉及更多内容。它使用 TypeInfo 参数来查找对象中包含的所有托管类型并初始化它们。这是一个递归过程,因为例如记录可能包含本身就是结构类型的成员。您可以在 RTL 源代码中看到所有血淋淋的细节。

对于System._Dispose,它会调用System._Finalize,然后调用FreeMemSystem._FinalizeSystem._Initialize 非常相似,只不过它最终确定托管类型而不是初始化它们。

对于性能敏感的 Delphi 用户来说,长期以来,System._InitializeSystem._Finalize 都是在运行时类型信息之上以这种方式实现的。这些类型在编译时是已知的,并且可以编写编译器来内联初始化和终结,这将带来更好的性能。

关于delphi - New 和 Dispose 内部做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34854646/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com