如何判断shared_ptr是否已被序列化到boost archive
基于Boost Serialization实现智能指针共享所有权校验的方案
是的,Boost Serialization内置了已序列化对象的追踪机制,你可以直接复用该机制实现你的校验需求,无需自行维护全局/上下文的指针映射表。
核心可用接口
你可以使用输出archive内置的lookup_pointer方法完成校验:
- 该方法的入参是待检查的指针对象的裸地址,返回值如果不为空,则代表该指针指向的内存对象已经被当前archive记录过,也就是出现了你要检测的共享所有权场景。
- 校验逻辑仅需要在序列化的保存阶段执行,避免加载存档时误触发异常。
代码实现示例
你只需要修改自定义SmartPointer类的序列化函数即可:
#include <stdexcept> #include <boost/serialization/base_object.hpp> // 你的自定义SmartPointer类的serialize方法 template<class Archive> void serialize(Archive & ar, SmartPointer & ptr, const unsigned int version) { // 仅在存档输出阶段做校验 if constexpr (Archive::is_saving::value) { if (ptr.get() != nullptr) { // 查询该指针是否已经被当前序列化流程追踪过 const void* already_tracked = ar.lookup_pointer(ptr.get()); if (already_tracked != nullptr) { throw std::runtime_error("检测到SmartPointer存在共享所有权"); } } } // 保留原有的父类shared_ptr序列化逻辑 ar & boost::serialization::base_object<boost::shared_ptr<typename SmartPointer::element_type>>(*this); }
注意事项
- 这套方案不需要修改其他业务类的序列化实现,嵌套对象的遍历逻辑完全由已有的序列化流程自动完成,符合你复用现有序列化能力的需求。
- Boost默认的所有输出archive(二进制/文本/XML)默认都启用了对象追踪特性,只要你没有给相关类显式指定
boost::serialization::track_never的追踪策略特化,校验逻辑就可以正常生效。 - 如果需要给部分类豁免检查,可以给对应类加标记类模板特化,在校验逻辑中判断指针指向的类型是否属于豁免范围即可。
内容的提问来源于stack exchange,提问作者user152508
相关产品推荐
相关产品推荐

