C或C++中的任何可克隆对象池实现?

arc*_*lin 5 c++ boost clone pool object-pooling

这可能看起来很奇怪,但我会尝试将其合理化.我目前广泛使用boost.object_poolshared_ptr一起使用,最近我遇到了一种情况,我需要拍摄当前程序状态的快照,以便进行全尺寸重放/回滚/快进等功能.

所以我不是试图克隆一个对象池在其他地方使用,这显然不会起作用,因为即使我被boost.pool的接口允许这样做(我不是这样),也没有指向块的有效指针在那个新克隆的游泳池里,它只会毫无意义.但我的用例是,如果有重放/回滚需求,我想将其" 粘贴 "回原始池中.

我当然可以手动复制和克隆所有状态,对象和子状态,子对象和子子...然后将它们打包成快照,并希望一切都会正确,但鉴于复杂性,这很容易出错该项目已经有了,并且它要比我直接复制内存慢得多.使用Command模式(或类似物)来实现undo-redo也是不可能的,因为undo-redo机制不是我的意图.

我只是想知道我是否使用顽固的传统C方式从头开始再做项目,而简单的memcpy(snapshot,all_states,size)调用几乎可以完成所有工作.

我还有其他选择吗?是否有任何boost.object_pool实现允许您克隆底层内存区域?在考虑到这种情况的情况下,侵入性地刺激boost.object_pool是一个合理的选择吗?

Mat*_* M. 2

从来没听说过。

正如您所指出的,这里的主要问题是对象之间可能存在相互依赖关系,这需要在创建副本时更新指针。当然不是微不足道的。

我可以想到两种可能的解决方案:

  • 持久性
  • 序列化

持久性是指永远不会改变现有状态。当您更改状态时,您将创建一个新快照,该快照引用除新位之外的旧状态。例如,它通常用于数据库的 MVCC 实现,并且在函数式编程世界中普遍存在。如果您尝试保留太多引用,这也是导致空间泄漏的好方法。最后,它需要深度的重新设计。

序列化是关于持久状态,但以不同的格式。您以序列化格式(无论是文本还是二进制)转储当前状态,并且可以通过读取序列化缓冲区来重新创建它。您甚至可以对序列化缓冲区应用压缩传递以节省一些内存。

既然您已经在使用 Boost,那么很高兴了解它Boost.Serialization可以自动处理对象图(呃!),而且我认为已经正确处理了boost::shared_ptr. 这里可能是您的最佳选择。