我对 Delphi 有点陌生,这个问题只是我好奇。 (我也只是偶然尝试使用它,结果发现我不应该这样做。)
如果您查看文档TObject.InitInstance http://docwiki.embarcadero.com/Libraries/XE4/en/System.TObject.InitInstance它告诉你不要使用它,除非你要重写NewInstance
。该方法也是公开的。如果用户不应该调用它,为什么不对其进行保护呢?
由于我在 1992 年中期整个 Delphi 事件开始时就在场,所以这个问题可能有几个答案。如果您查看 Delphi 1 中 TObject 的原始声明,就会发现 TObject 上没有任何受保护/私有成员。这是因为在 Delphi 开发的早期阶段,随着该语言异常的引入,异常是从不同的堆比其他对象。这就是 NewInstance/InitInstance/CleanupInstance/FreeInstance 函数的起源。在您可以真正控制的类类型上重写这些函数where分配了一个对象。
近年来,我使用此功能创建了字面上“回收”的对象实例的缓存。通过拦截 NewInstance 和 FreeInstance,我创建了一个系统,其中实例在解除分配时不会返回到堆,而是放置在无锁/低锁链表上。这使得分配/释放特定类型的实例变得更快,并消除了对内存管理器的大量访问。
通过将 InitInstance 设为公共(其相反是 CleanupInstance),这将允许从其他实用程序函数调用这些方法。在上面我提到的情况下,可以在现有内存块上调用 InitInstance,而不必仅从 NewInstance 调用。假设 NewInstance 调用管理上述缓存的通用函数。类实例的“范围”丢失了,因此调用 InitInstance 的唯一方法是它是公共的。
总有一天,我们可能会发布执行我上面描述的操作的代码……目前它是内部“研究”项目的一部分。
哦,顺便说一句,也是一个历史教训......在 Delphi 1 版本之前,如何分配/释放 Exception 实例的设计又回到了使用与所有其他对象相同的堆。由于整体集体失误,假设我们需要分配所有异常对象实例来“保护”内存不足的情况。我们推断,如果我们尝试引发异常,因为内存管理器“内存不足”,那么我们将如何分配异常实例!?我们已经知道那时没有记忆!因此,我们决定对所有异常都需要一个单独的堆...直到 Chuck Jazdzewski 或 Anders Heijlsberg(我具体忘记了是哪一个)找到了一个简单且相当聪明的解决方案...只是预分配启动时内存不足异常!我们仍然需要控制异常是否应该真正被释放(异常实例在处理后会自动释放),因此整个 NewInstance/FreeInstance 机制仍然存在。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)