Boost序列化含unique_ptr指向对象的类的实现问询
序列化含std::unique_ptr成员的类实现思路评审
问题背景
我有一个Class_A类对象,它由多个来自不同类Class_X、Class_Y、Class_Z……的对象组成,这些对象通过std::unique_ptr指向。假设Class_X、Class_Y、Class_Z等子类仅包含基本数据类型。
我尝试对Class_A进行序列化,已为其添加save和load方法,且Class_A的基本数据类型成员序列化已正常工作。现在需要扩展实现Class_X的序列化,并调整Class_A的序列化逻辑。
现有代码
Class_A头文件
// Class A HPP: private: int m_classXID{}; std::unique_ptr<Class_X> m_classXObject; ... template<class Archive> void save(Archive& ar, const unsigned int version) const; template<class Archive> void load(Archive& ar, const unsigned int version); template<class Archive> void serialize(Archive& ar, const unsigned int version); ...
Class_A初始实现(CPP文件)
// Class A CPP: ... template<class Archive> void Class_A::save(Archive& ar, const unsigned int version) const { ar << m_classXID; } template<class Archive> void Class_A::load(Archive& ar, const unsigned int version) { ar >> m_classXID; } template<class Archive> void Class_A::serialize(Archive& ar, const unsigned int version) { boost::serialization::split_member(ar, *this, 1); } ...
Class_X头文件
// Class X HPP: private: // 让序列化框架访问serialize函数 friend class boost::serialization::access; // 序列化方法 template<class Archive> void serialize(Archive& ar, const unsigned int version);
Class_X初始实现(CPP文件)
// Class X CPP: template <typename Archive> void Class_X::serialize(Archive& ar, const unsigned int version) { ar& m_firstInt; ar& m_secondInt; ar& m_thirdInt; ar& m_fourthInt; ...; }
修改后的Class_A序列化实现
template<class Archive> void Class_A::save(Archive& ar, const unsigned int version) const { ar << m_classXID; ar << m_classXObject; } template<class Archive> void Class_A::load(Archive& ar, const unsigned int version) { ar >> m_classXID; m_classXObject = std::make_unique<Class_X>(); ar >> m_classXObject; } template<class Archive> void Class_A::serialize(Archive& ar, const unsigned int version) { boost::serialization::split_member(ar, *this, 1); }
实现思路评审
Class_X的序列化逻辑是正确的
- 通过声明
boost::serialization::access为友元,确保序列化框架能访问类的私有成员,这是Boost.Serialization的标准用法。 serialize方法中使用ar&操作符处理所有基本类型成员,统一支持序列化和反序列化,符合基本类型序列化的规范。
- 通过声明
Class_A的调整思路方向正确
- Save阶段:先序列化标识ID
m_classXID,再直接序列化m_classXObject——Boost.Serialization原生支持std::unique_ptr的序列化,只要指向的Class_X已正确实现序列化逻辑,直接归档智能指针是可行的。 - Load阶段:先反序列化
m_classXID,然后必须先通过std::make_unique<Class_X>()创建Class_X的实例(因为std::unique_ptr默认是空指针,反序列化需要有可写入的对象实例),之后再反序列化m_classXObject,这一步完全符合Boost.Serialization对智能指针反序列化的要求。
- Save阶段:先序列化标识ID
LINK2019错误的根源
- 错误本质是C++模板的编译特性导致:模板函数的实现放在了
.cpp文件中,而模板需要在调用点可见完整定义才能实例化。将所有序列化相关的模板代码(包括save、load、serialize)移到头文件后,链接器能找到模板实例的定义,错误自然解决。
- 错误本质是C++模板的编译特性导致:模板函数的实现放在了
更新说明
感谢关于模板需仅放在头文件的提示!将所有模板代码移到头文件后问题已解决。
内容的提问来源于stack exchange,提问作者JamalNewtron
相关产品推荐
相关产品推荐

