实现对象跟踪,就像在Boost :: Serialization中一样

时间:2012-01-23 07:58:46

标签: c++ boost object-identity

我正在为C ++中的对象图实现一个“克隆”函数,部分问题是确保如果有两个指向同一对象的指针,则不会克隆两次。我这样做是通过保持map<void*, void*>来保持原始对象作为键,克隆版本作为值。克隆对象时,我使用模板函数来检查对象是否在地图中 - 如果是,我用static_cast<T*>返回它,否则,我克隆它并将原始文件存储并在地图中克隆隐式转换为void*

这个方案的问题在于,如果一个对象在两个地方被不同的类型引用(例如,通过接口与具体类型),那么转换为void*可能不会产生相同的值。这意味着对象被克隆了两次。

我在网上查找了现有的解决方案,并意识到Boost.Serialization必须处理同样的问题。但是在浏览了它的源代码之后,我找不到实际跟踪对象指针的部分。

任何人都可以通过建议一个有效的设计,或通过指出Boost代码的一部分来做到这一点吗?

2 个答案:

答案 0 :(得分:4)

在存储之前,使用dynamic_cast<void*>转换指针 - 这将为您提供指向大多数派生对象的的无效指针;对于相同的对象,此void指针将存储相同的地址。

另见this question

答案 1 :(得分:1)

我不相信boost序列化以一种超级聪明的方式处理这个问题。查看base_object函数 - 您似乎必须手动说出基类是什么。从这里可以明显看出如何获得相同的指针。另请注意,对于序列化派生类,只有虚拟类才能正确保存,非虚拟类,如标准布局类型,必须序列化派生类。我不知道在这种情况下他们是否处理共享指针。

所以基本的想法是,如果你有一个虚拟类,那么基类必须具有各种“串行”功能。如果你转换到这个基础,你有一个公共指针,仍然可以调用虚拟串行函数。

您可能最好只创建一个全局identify<T>模板,并将其专门用于所有需要它的类型。可能容易出错,但升级方法决不会避免错误。

我已经做了很多关于boost序列化的工作,但是避免了指针逻辑 - 它只是让人感到困惑,所以我基本上只是不做那个级别的序列化(我的序列化数据中没有指针)。 / p>