自定义字符串管理器的实现(高级方法)

在特殊情况下,你可能想要实现一个自定义字符串管理器,该管理器不只是更改用于分配内存的堆。 在这种情况下,必须手动实现 IAtlStringMgr 接口,作为自定义字符串管理器。

为此,首先必须了解 CStringT 如何使用该接口来管理其字符串数据。 每个 CStringT 实例都有指向 CStringData 结构的指针。 此可变长度结构包含有关字符串的重要信息(例如长度),以及字符串的实际字符数据。 每个自定义字符串管理器都负责根据 CStringT 的请求分配和释放这些结构。

CStringData 结构包括四个字段:

  • pStringMgr:此字段指向用于管理此字符串数据的 IAtlStringMgr 接口。 当 CStringT 需要重新分配或释放字符串缓冲区时,它会调用此接口的 Reallocate 或 Free 方法,将 CStringData 结构作为参数传递。 在字符串管理器中分配 CStringData 结构时,必须将此字段设置为指向自定义字符串管理器。

  • nDataLength:此字段包含缓冲区中存储的字符串的当前逻辑长度,不包括终止 null。 CStringT 会在字符串长度更改时更新此字段。 分配 CStringData 结构时,字符串管理器必须将此字段设置为零。 重新分配 CStringData 结构时,自定义字符串管理器必须使此字段保持不变。

  • nAllocLength:此字段包含在不重新分配的情况下可存储在此字符串缓冲区中的最大字符数(不包括终止 null)。 每当 CStringT 需要增加字符串的逻辑长度时,它都会首先检查此字段,以确保缓冲区中有足够的空间。 如果检查失败,CStringT 会调用自定义字符串管理器来重新分配缓冲区。 分配或重新分配 CStringData 结构时,必须将此字段至少设置为 IAtlStringMgr::AllocateIAtlStringMgr::Reallocate 的 nChars 参数中请求的字符数。 如果缓冲区中的空间多于请求的空间,则可以设置此值以反映可用空间的实际量。 这样,CStringT 就可以增大字符串以填充整个分配的空间,然后才能重新调用字符串管理器来重新分配缓冲区。

  • nRefs:此字段包含字符串缓冲区的当前引用计数。 如果值为 1,则表明 CStringT 的单个实例在使用缓冲区。 此外,允许实例读取和修改缓冲区的内容。 如果该值大于 1,则表明 CStringT 的多个实例可以使用缓冲区。 由于共享字符缓冲区,因此 CStringT 实例只能读取缓冲区的内容。 若要修改内容,请让 CStringT 先创建缓冲区的副本。 如果值为负,则表明 CStringT 的一个实例在使用缓冲区。 在这种情况下,缓冲区被视为已锁定。 当 CStringT 实例使用锁定缓冲区时,没有其他 CStringT 实例可以共享缓冲区。 这些实例只能在操作内容之前创建缓冲区的副本。 此外,使用锁定缓冲区的 CStringT 实例不会尝试共享分配给它的任何其他 CStringT 实例的缓冲区。 在这种情况下,CStringT 实例会将另一个字符串复制到锁定的缓冲区中。

    分配 CStringData 结构时,必须设置此字段以反映缓冲区允许的共享类型。 对于大多数实现,请将此值设置为 1。 这允许常见的写入时复制共享行为。 但是,如果字符串管理器不支持共享字符串缓冲区,请将此字段设置为锁定状态。 这强制 CStringT 只将此缓冲区用于已分配它的 CStringT 实例。

另请参阅

使用 CStringT 进行内存管理