实现对象跟踪,如在 Boost::Serialization 中

Implementing object tracking, like in Boost::Serialization

本文关键字:Serialization Boost 如在 对象 跟踪 实现      更新时间:2023-10-16

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

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

我在网上寻找现有的解决方案,并意识到Boost.Serialization必须处理同样的问题。但是在搜索其来源后,我找不到实际跟踪指向对象的指针的部分。

任何人都可以通过建议有效的设计或指出 Boost 代码中执行此操作的部分来提供帮助吗?

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

另请参阅此问题。

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

所以基本的想法是,如果你有一个虚拟类,基必须有一个"串行"函数。如果转换为此基数,则具有公共指针,并且仍然可以调用虚拟串行函数。

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

我已经在 boost 序列化方面做了很多工作,但避免了指针逻辑 - 它变得非常混乱,所以我基本上不做那个级别的序列化(我的序列化数据中没有指针(。