boost.serialization要求类必须显式声明serialize函数,不能自动反射;需用ar & member语法逐个处理可序列化成员,并注意归档类型、流模式及类型导出等细节。

Boost.Serialization 要求类必须显式声明序列化函数
Boost.Serialization 不是自动反射,它不会读取类成员变量名或类型来生成序列化逻辑。你必须为每个要序列化的类添加一个 serialize 成员函数(或非成员友元函数),并在其中显式调用 ar & member 语法。
常见错误是直接对类实例调用 boost::archive::text_oarchive,结果编译失败,报错类似:no matching function for call to ‘serialize(...)。
- 类必须有 public 的
serialize函数,或声明friend class boost::serialization::access - 所有被
&的成员变量必须本身可序列化(内置类型、STL 容器、已适配的自定义类) - 如果类有指针成员,需额外处理(如用
BOOST_SERIALIZATION_SPLIT_MEMBER()分离 save/load,或改用shared_ptr)
选对归档类型:text_oarchive vs binary_oarchive vs xml_oarchive
磁盘序列化不是只有一种方式——不同归档类型影响可读性、体积、跨平台性和性能。
text_oarchive 生成人类可读的 ASCII 文本,调试方便,但体积大、解析慢;binary_oarchive 二进制格式紧凑快速,但不可读、不跨字节序平台;xml_oarchive 可读且结构清晰,但开销最大。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 开发调试阶段优先用
boost::archive::text_oarchive - 生产环境存大量数据时用
boost::archive::binary_oarchive,但注意不要在不同 CPU 架构间混用文件 - 需要和外部系统交换数据时,
xml_oarchive更稳妥(需链接libboost_serialization)
写文件必须用 std::ofstream 的 binary 模式(尤其 binary_oarchive)
使用 binary_oarchive 时,如果 std::ofstream 没设 std::ios::binary 标志,Windows 下会把 \x0A(换行)误转成 \x0D\x0A,导致反序列化失败,报错如:input stream error 或 unregistered class。
- 正确写法:
std::ofstream ofs("data.bin", std::ios::binary); -
text_oarchive和xml_oarchive对模式不敏感,但统一用binary更安全 - 记得检查
ofs.is_open(),否则运行时archive构造可能不报错,但后续写入静默失败
反序列化前必须确保类类型已注册(涉及继承或指针时)
如果你序列化了 std::shared_ptr<base>,而实际指向 Derived,反序列化时 Boost 需知道如何构造 Derived 实例。这要求在任意归档对象创建前,调用 BOOST_CLASS_EXPORT(Derived) 或在源文件中加 BOOST_CLASS_EXPORT_IMPLEMENT(Derived)。
漏掉这步会导致运行时报错:unregistered class - derived class not registered or exported。
- 导出宏必须出现在
.cpp文件里(不能只在头文件声明),否则链接时报undefined reference to ... - 基类若含虚函数,建议加
BOOST_SERIALIZATION_ASSUME_ABSTRACT(Base) - 纯数据类(无继承/指针)可跳过导出,但一旦用了多态指针,就必须导出具体类型
Boost.Serialization 磁盘序列化真正卡住人的地方,往往不在语法,而在类型导出时机、流打开模式、以及 serialize 函数是否真的覆盖了所有需要持久化的状态——尤其是 const 成员、缓存字段或 lazy 初始化的成员,它们不会自动参与序列化,得手动判断是否保存/恢复。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










