gpt4 book ai didi

Delphi - 为什么 TObject.InitInstance 是公共(public)的?

转载 作者:行者123 更新时间:2023-12-03 14:40:44 45 4
gpt4 key购买 nike

我对 Delphi 有点陌生,这个问题只是我好奇。 (我也只是偶然尝试使用它,结果发现我不应该这样做。)

如果您查看 TObject.InitInstance 的文档它告诉您不要使用它,除非您要覆盖 NewInstance。该方法也是公开的。如果用户不应该调用它,为什么不对其进行保护呢?

最佳答案

自从 1992 年中期整个 Delphi 事件开始时我就在场,这个问题可能有几个答案。如果您查看 Delphi 1 中 TObject 的原始声明,就会发现 TObject 上没有任何 protected /私有(private)成员。这是因为在 Delphi 开发的早期阶段,随着语言中异常的引入,异常是从与其他对象不同的堆中分配的。这就是 NewInstance/InitInstance/CleanupInstance/FreeInstance 函数的起源。在类类型上重写这些函数,您可以从字面上控制对象的分配位置。

近年来,我使用此功能创建了字面上“回收”的对象实例的缓存。通过拦截 NewInstance 和 FreeInstance,我创建了一个系统,其中实例在解除分配时不会返回到堆,而是被放置在无锁/低锁链表上。这使得分配/释放特定类型的实例变得更快,并消除了对内存管理器的大量访问。

通过将 InitInstance 设为公共(public)(其相反是 CleanupInstance),这将允许从其他实用程序函数调用这些方法。在上面我提到的情况下,可以在现有内存块上调用 InitInstance,而不必仅从 NewInstance 调用。假设 NewInstance 调用管理上述缓存的通用函数。类实例的“范围”丢失了,因此调用 InitInstance 的唯一方法就是将其公开。

有一天,我们可能会发布执行我上面描述的操作的代码......目前它是内部“研究”项目的一部分。

哦,顺便说一句,也是一个历史教训......在 Delphi 1 版本之前,如何分配/释放 Exception 实例的设计又回到了使用与所有其他对象相同的堆。由于整体集体失误,假设我们需要分配所有异常对象实例来“保护”内存不足的情况。我们推断,如果我们尝试引发异常,因为内存管理器“内存不足”,那么我们将如何分配异常实例!?我们已经知道那时没有内存!因此,我们决定对所有异常都需要一个单独的堆...直到 Chuck Jazdzewski 或 Anders Heijlsberg(我具体忘记是哪一个)找到了一个简单且相当聪明的解决方案...只需预分配 启动时出现内存不足异常!我们仍然需要控制异常是否应该真正被释放(异常实例在处理后会自动释放),因此整个 NewInstance/FreeInstance 机制仍然存在。

关于Delphi - 为什么 TObject.InitInstance 是公共(public)的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22540670/

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