Delphi - 为什么是TObject.InitInstance public? [英] Delphi - Why is TObject.InitInstance public?

查看:152
本文介绍了Delphi - 为什么是TObject.InitInstance public?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Delphi有点新鲜,而这个问题只是我好奇。 (我也只是试图使用它只是为了发现我不应该。)



如果您查看 TObject.InitInstance 它告诉你不要使用它,除非你重写 NewInstance 。该方法也是公开的。为什么不保护用户永远不会调用它?

解决方案

在1992年年中开始,这个问题可能有几个答案。如果您在Delphi 1中查看TObject的原始声明,则TObject上没有任何受保护/私有成员。那是因为Delphi的开发很早,与引入语言异常一致,例外是从不同的堆分配给其他对象。这是NewInstance / InitInstance / CleanupInstance / FreeInstance功能的起源。在类类型上覆盖这些函数,您可以直接控制分配对象的



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



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



其中一天,我们可能会发送代码这就是我上面描述的内容,现在它是内部研究项目的一部分。



呵呵,另外还有一点历史课。在Delphi 1发行之前,将如何将Exception实例分配/释放的设计返回到使用与所有其他对象相同的堆。由于总体集体的错误,我们假设我们需要分配所有Exception对象实例来保护内存不足的情况。我们推断,如果我们尝试引发异常,因为内存管理器是内存不足,那么我们如何分配异常实例呢?我们已经知道那时没有记忆!所以我们决定,除了Chuck Jazdzewski还是Anders Heijlsberg(我忘记了哪一个)之外,所有异常都需要一个单独的堆,想出了一个简单而又聪明的解决方案...只需预先分配启动时出现内存异常!我们仍然需要控制是否应该实际释放异常(异常实例在被处理后被自动释放),所以整个NewInstance / FreeInstance机制仍然存在。


I'm somewhat new to Delphi, and this question is just me being curious. (I also just tried using it by accident only to discover I'm not supposed to.)

If you look at the documentation for TObject.InitInstance it tells you not to use it unless you're overriding NewInstance. The method is also public. Why not make it protected if the user is never supposed to call it?

解决方案

Since I was around when this whole Delphi thing got started back around mid-1992, there are likely several answers to this question. If you look at the original declaration for TObject in Delphi 1, there weren't any protected/private members on TObject. That was because very early on in the development of Delphi and in concert with the introduction of exceptions to the language, exceptions were allocated from a different heap than other objects. This was the genesis of the NewInstance/InitInstance/CleanupInstance/FreeInstance functions. Overriding these functions on your class types you can literally control where an object is allocated.

In recent years I've used this functionality to create a cache of object instances that are literally "recycled". By intercepting NewInstance and FreeInstance, I created a system where instances are not returned to the heap upon de-allocation, rather they are placed on a lock-free/low-lock linked list. This makes allocating/freeing instances of a particular type much faster and eliminates a lot of excursions into the memory manager.

By having InitInstance public (the opposite of which is CleanupInstance), this would allow those methods to be called from other utility functions. In the above case I mentioned, InitInstance could be called on an existing block of memory without having to be called only from NewInstance. Suppose NewInstance calls a general purpose function that manages the aforementioned cache. The "scope" of the class instance is lost so the only way to call InitInstance is of it were public.

One of these days, we'll likely ship the code that does what I described above... for now it's part of an internal "research" project.

Oh, as an aside and also a bit of a history lesson... Prior to the Delphi 1 release, the design of how Exception instances were allocated/freed was returned to using the same heap as all the other objects. Because of an overall collective misstep it was assumed that we needed to allocate all Exception object instances to "protect" the Out of memory case. We reasoned that if we try and raise an exception because the memory manager was "out of memory", how in the blazes would we allocate the exception instance!? We already know there is no memory at that point! So we decided that a separate heap was necessary for all exceptions... until either Chuck Jazdzewski or Anders Heijlsberg (I forget exactly which one), figured out a simple, rather clever solution... Just pre-allocate the out of memory exception on startup! We still needed to control whether or not the exception should ever actually be freed (Exception instances are automatically freed once handled), so the whole NewInstance/FreeInstance mechanism remained.

这篇关于Delphi - 为什么是TObject.InitInstance public?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆