禁用裸 memcpy 反序列化含 STL 成员或非 POD 类型的对象;推荐使用 boost::serialization 或 JSON(如 nlohmann::json);需严格校验流状态、版本兼容性及对象内部状态重建。

用 std::ifstream 读二进制文件 + 手动 memcpy 容易崩
直接把内存布局写进文件再原样读回来,看似最简单,实际极不可靠。类里只要带 std::string、std::vector、虚函数表、指针成员,或者跨平台/跨编译器/不同优化等级下,sizeof(MyClass) 都可能变化,memcpy 会把野指针或错误长度的字符串头塞进对象里,运行时崩溃或数据错乱是常态。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 禁用裸
memcpy反序列化含 STL 成员或非 POD 类型的对象 - 若坚持二进制直读,仅限纯
struct(无构造函数、无虚函数、所有成员为基本类型或固定大小数组),且需加#pragma pack(1)和static_assert(std::is_pod_v<mystruct>)</mystruct> - 写入前用
write(reinterpret_cast<const char>(&obj), sizeof(obj))</const>,读取后必须做字段级校验,不能假设字节流“一定对”
boost::serialization 是最省心的通用方案
它能自动处理 std::string、容器、继承关系、指针共享等复杂情况,序列化格式稳定,支持文本和二进制存档,且跨编译器兼容性好。缺点是需要为每个类显式定义 serialize 成员函数。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 在类内声明
template<class archive> void serialize(Archive& ar, const unsigned int version)</class> - 使用
ar & member1 & member2;顺序声明字段,顺序必须和序列化时完全一致 - 二进制存档用
boost::archive::binary_iarchive,文本存档用boost::archive::text_iarchive,后者便于调试但体积大、稍慢 - 注意
BOOST_CLASS_VERSION(MyClass, 1)版本宏——升级类字段后,老文件仍可读,新字段会用默认值填充
自己写文本解析(如 JSON)适合调试和跨语言场景
用 nlohmann::json 或 rapidjson 把对象转成 JSON 写文件,再从 JSON 构造对象,好处是人眼可读、易调试、天然支持版本迁移和字段缺失容错。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 不要手动拼接 JSON 字符串,用库的
json::parse()和json::dump() - 反序列化时用
json.at("field_name").get<t>()</t>而非json["field_name"].get<t>()</t>,前者抛异常更早,避免静默错误 - 对可选字段,先用
json.contains("field")判断,再取值;对必填字段,用at()强校验 - 注意浮点数精度:JSON 规范不保证
double精确还原,若需严格一致,改用整数单位(如微秒、分币)存储
反序列化失败时,std::ifstream::failbit 和异常捕获必须同时检查
只检查 if (!ifs) 会漏掉部分读取成功但结构损坏的情况,比如 JSON 格式错位、二进制存档版本不匹配、字段类型不一致等,这些往往不会触发流状态位,但会导致后续逻辑出错。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 打开文件后立刻设置
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit) - 在 try/catch 外再加一层
if (ifs.peek() == std::char_traits<char>::eof())</char>判断空文件 - 对
boost::serialization,捕获boost::archive::archive_exception并检查code成员(如boost::archive::archive_exception::unregistered_class) - 对 JSON,
json::parse()抛异常时,e.what()会包含具体行号和字符位置,别忽略它
真正麻烦的不是读文件,而是对象内部状态重建——比如反序列化后的 std::shared_ptr 指向谁、缓存是否清空、观察者列表要不要重连。这些没法靠序列化库自动处理,得在 serialize 函数末尾或构造函数里显式补全。



















