这可能看起来很奇怪,但我会尝试将其合理化。我目前广泛使用 boost.object_pool 和 shared_ptr ,最近我遇到了一种情况,我需要拍摄当前程序状态的快照,以便使功能像完整一样-scale 重播/回滚/快进。
所以我没有尝试克隆一个对象池在其他地方使用,这显然不会起作用,因为即使我被boost.pool的接口(我不是)允许这样做,也没有有效的指针指向那个新克隆的游泳池中的块,这将是毫无意义的。但是我的用例是,如果有重放/回滚需求,我想“粘贴”将它重新放回原始池中。
我当然可以手动复制和克隆所有状态,对象和子状态,子对象和子子...然后将它们打包成快照,并希望一切都会正确,但这很容易出错鉴于项目已经具备的复杂性,并且它比我直接复制内存要快得多。使用Command模式(或类似物)来实现undo-redo也是不可能的,因为undo-redo机制不是我的意图。
我只是想知道我是否使用顽固的传统C方式从头开始再做项目,而简单的memcpy(snapshot,all_states,size)调用几乎可以完成所有工作。
我还有其他选择吗?是否有任何boost.object_pool实现允许您克隆底层内存区域?在考虑到这种情况的情况下,侵入性地刺激boost.object_pool是一个合理的选择吗?
答案 0 :(得分:2)
不是我知道的。
正如您所指出的,这里的主要问题是对象之间可能存在相互依赖关系,这需要在复制时更新指针。当然是非平凡的。
我可以想到两种可能的解决方案:
持久性是永远不会改变现有状态。当您更改状态时,您将创建一个新快照,该快照引用除新位之外的旧状态。例如,它通常用于数据库的MVCC实现,并且在函数式编程世界中普遍存在。如果你试图保留太多的引用,它也是一个很好的方法来获取空间泄漏。最后,它需要深度重新设计。
序列化是关于持久化状态,但格式不同。您以序列化格式(无论是文本格式还是二进制格式)转储当前状态,并且可以通过读取序列化缓冲区来重新创建它。您甚至可以在序列化缓冲区上应用压缩传递来节省一些内存。
由于您已经在使用Boost,所以很高兴得知Boost.Serialization
自动处理对象图(呃!),我认为已经正确处理了boost::shared_ptr
。这可能是你最好的选择。