目前在我们的计划中使用的很多地方之一是记录.
这些记录很多都保存在AVL树中.
使用的AVL树是通用的,它包含一个指向多个字节(ElemSize)的指针,这些指针到目前为止运行良好.
AVL树中每条记录的内存使用GetMem分配,并使用Move复制.
但是,如果string是指向引用计数结构的指针,则将内存复制回记录不再有效,因为引用的sting经常被释放(通过引用计数自动).
只有一个指针和“数据块”的大小,我认为不可能增加字符串的引用计数.
我正在寻找一种方法来获取在AVL树中存储记录时要考虑的叮咬的引用计数.
我可以将记录类型传递给树构造函数,然后将指针强制转换为此类型,从而增加引用吗?或者类似的修复,我可以将更改隔离到主要在AVL单元中并调用它的构造函数.
用于分配存储AVL记录的空间的当前代码; XData是指向要存储的记录的指针:
New(RootPtr); { create new memory space } GetMem(RootPtr^.TreeData, ElemSize); WITH RootPtr^ DO BEGIN { copy data } Move(XData^, RootPtr^.TreeData^, ElemSize);从本质上讲,您要问的问题是:
How can I allocate, copy and deallocate a record when all I know about its type is its size?
简单的答案是,如果记录不包含托管类型,则可以使用GetMem,Move和FreeMem.您希望使用包含Delphi字符串的记录,这些字符串是受管理的.因此,使用GetMem和Move的当前方法是不够的.
有很多方法可以解决这个问题.您可以编写自己的代码来进行引用计数,只要您知道托管类型在记录中的位置即可.我不推荐这个.您可以将您的用户数据设为一个类,并使用多态来提供帮助.
我想讨论的选项继续支持记录,并且确实允许用户选择他们喜欢的任何类型.理由如下:
如果类型包含托管类型,则对其进行操作需要了解类型.如果树是通用的,那么它就不具备这种知识.因此,知识必须由树的用户提供.
这会引导您参加活动.让树提供用户可以提供处理程序的事件.类型看起来像这样:
type PTreeNodeUserData = type Pointer; TTreeNodeCreateUserDataEvent = function: PTreeNodeUserData of object; TTreeNodeDestroyUserDataEvent = procedure(Data: PTreeNodeUserData) of object; TTreeNodeCopyUserDataEvent = procedure(Source, Dest: PTreeNodeUserData) of object;
然后,您可以安排树发布具有用户可以订阅的这些类型的事件.
关键在于,这允许树的用户提供关于用户数据类型的缺失知识.