在从C ++到Delphi的移植代码的过程中,通常必须使用STL集合来输入代码。德尔菲提供的一组收藏非常苦风,因此有时
很难找到合适的替代品。有时,您会遇到对象放置在堆栈中或使用其自己的内存分配器的代码。
我真的不喜欢建议的数据刷新模式。要更新数据,我需要从集合中检索其中的值,更新值,然后将更改的值重新放回。这需要至少两个额外的副本操作。我们不能将数据项作为VAR参数传递给过程。
集合无法更改内存的分配方式。对象和记录的内存是从一个共享堆中分配的。使用后,必须小心地将内存返回堆。正确释放内存并不总是一项琐碎的任务,而且处理器的时间和编程编写此代码的时间都需要时间。在STL中,您可以为各种收藏集指定自己的内存分配器。
该实施依赖于记录和指针。到目前为止,我认为没有办法使用标准对象实现我想要的东西。对象的创建和破坏使用共享的内存堆。无法将对象放在呼叫堆栈上。不支持旧的旧“对象”,并不支持为此类型的添加新功能。
该集合实现依赖于基于类型内存区域的机制内存管理。使用键入的内存区域可以简化许多任务的解决方案:
释放内存的任务变得更加容易,并且可以更快地完成。
众所周知,标准内存管理器必须是线程安全的事实。只有一个线程可以在任何给定时间访问内存管理器。分配和释放存储器使用相互排除机制,这不是一个快速的操作,尤其是在内存大量碎片片上。使用单独的键入内存区域时,我们仅在增加所需内存并在使用后删除结构时才参考标准内存管理器。
支持具有指定内存分配器的能力的基本结构。列表的元素通过指针访问。通常,值的内存位于所谓的分段内存区域中,在操作过程中不会移动。如果有必要增加区域的内存,则将为其分配附加的内存段。这意味着我们可以通过指针访问该区域中的数据项。
对于数组,我们使用所谓的连续内存区域。通过索引访问数据项。如有必要,增加区域的内存,为其分配了大尺寸的段,并将来自当前存储器段的数据复制到新段。复制数据后,将删除旧段。
最终,通过指针进行工作非常方便。代码变得更简单,更简洁。但是,如果您没有指针的经验,则很容易“射击自己”。对于封装的粉丝,您可以将所需的结构汇总为私人领域。接下来,我们仅通过覆盖公共部分中所需的方法和属性来打开接口的必要部分。如果我们放入内联选项,我们会避免额外的费用。 Delphi编译器将不会为覆盖方法生成代码。在方法调用的位置,将直接调用聚合结构方法。
TsgTuple<T1, ...>通用元素TsgArray<T>通用数组,带有来自共享内存区域的内存分配TsgList<T>通用值列表TsgRecordList<T>指针访问的值的通用列表TsgLinkedList<T>通用双向链接列表TsgForwardList<T>通用单向链接列表TsgHashMap<Key, T>通用无序词典TsgMap<Key, T>基于2-3棵树的通用有序词典TsgSet<Key>基于2-3棵树的通用集TsgPointerArray未型指针清单TsgPointerList未型的指针访问的值列表TCustomLinkedList未型双向链接列表TsgCustomTree棵树我们已经开始添加Delphi迭代器。现在,我们可以for p in List do;最有趣的是,我们使用记录来实现迭代器,并且它有效!与使用对象相比,生成的代码效率更高,而且很不错,没有对堆的调用,迭代器的变量位于堆栈上。事实证明,这对我来说是一个令人惊喜的惊喜!
指定内存分配器的能力也意味着我们主要与记录一起工作。通常,某些结构使用一个或多个内存区域,这是一个简单的内存管理器。使用结构后,我们有机会通过释放内存区域来返回所有占用的内存。我们使用继承有局限性。在某些情况下,我们可以用聚合和助手代替继承。通常用于实施集合,这不是问题。使用记录可以堆叠收集。有时这很方便。
对象池允许您在创建对象是内存密集型或创建有限数量的某个类型对象时管理结构的重复使用。
如果我们停止使用某些东西,那么并不总是值得删除结构或对象。通常,必须重新创建对象。