boost.serialization序列化需满足三条件:裸指针等受限类型须注册,serialize()必须public或friend以支持adl查找,binary_archive与text_archive差异在于跨平台性与精度而非逻辑;std::unique_ptr需注册派生类并管理版本号。

Boost.Serialization 不能直接序列化裸指针、未注册的类或含非默认构造函数的对象,否则运行时崩溃或静默失败。
为什么 serialize() 函数必须是 public 或 friend?
Boost.Serialization 在归档(archive)写入/读取时,通过 ADL(Argument-Dependent Lookup)查找自由函数 serialize();它不调用成员函数,也不走虚函数表。如果该函数是私有成员,编译器会拒绝访问。
- 错误现象:
error: 'serialize' is a private member of 'MyClass' - 正确做法:在类内声明
friend void serialize(Archive&, MyClass&, const unsigned int);,并在类外定义 - 不推荐把
serialize()写成 public 成员函数——它会被误认为普通接口,且签名难匹配(Archive 类型模板参数无法推导) - 若用
BOOST_SERIALIZATION_SPLIT_MEMBER()拆分 save/load,同样需 friend 声明两个函数
binary_archive 与 text_archive 的实际差异不只是可读性
二者底层序列化逻辑一致,但二进制格式不跨平台、不跨 Boost 版本,text 格式虽可读却更占空间、解析更慢,且对浮点数精度有隐式截断。
- binary_archive:默认使用平台原生字节序和 sizeof,
boost::archive::binary_oarchive生成的文件在 x86_64 Linux 和 ARM macOS 上互不可读 - text_archive:输出类似
22 serialization::archive 17 0 0 1.2345678901234567e+00,其中浮点数按std::setprecision(17)输出,但读取时仍可能因 locale 导致解析失败 - portable_binary_archive 更安全,但需额外链接
libboost_serialization,且不支持所有类型(如std::function) - 生产环境优先选
boost::archive::binary_oarchive+ 明确版本锁定 + 同构部署
如何安全序列化含 std::unique_ptr 的对象?
Boost.Serialization 支持智能指针,但 std::unique_ptr 要求被指向类型已注册(BOOST_CLASS_EXPORT),且必须确保生命周期可控——反序列化后,原对象析构不会连带释放新分配内存。
- 错误写法:
std::unique_ptr<base> p = std::make_unique<derived>();</derived>但未注册Derived→ 运行时报unregistered class - derived class not registered or exported - 必须加:
BOOST_CLASS_EXPORT(Derived)(头文件中),且确保该宏在 archive 实例化前可见 - 若
Base是抽象类,还需BOOST_SERIALIZATION_ASSUME_ABSTRACT(Base) - 注意:反序列化时
unique_ptr会 new 新对象,原指针内容被完全替换,无需手动清理
最常被忽略的是版本号管理:serialize() 函数最后一个参数是版本号,但很多人写死 const unsigned int version = 0,后续字段增减却不更新——导致旧文件加载新结构时字段错位,出问题很难定位。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











