c++如何使用Cereal库进行序列化_c++现代化的序列化库【教程】

23次阅读

Cereal序列化核心三步:引入头文件、定义serialize函数、选jsON/Binary/xml存档;它轻量纯头文件、无需预编译,支持容器/智能指针/版本控制/继承

c++如何使用Cereal库进行序列化_c++现代化的序列化库【教程】

使用 Cereal 库进行 c++ 序列化,核心就三步:引入头文件、定义序列化函数、选择存档类型(json / Binary / XML)来读写。它轻量、头文件仅依赖、无需预编译或 IDL,是现代 C++ 项目中非常自然的序列化方案。

1. 快速接入 Cereal

Cereal 是纯头文件库,直接下载 red”>cereal/include/cereal 目录,加到项目 include 路径即可。CMake 中可这样引入:

include_directories(${CMAKE_SOURCE_DIR}/third_party/cereal/include)

无需链接任何库,也不需要生成代码 —— 它靠 C++ 模板和 ADL(参数依赖查找)自动发现序列化逻辑。

2. 为自定义类添加序列化支持

最常用方式是在类内部或外部定义 serialize 成员函数或非成员函数,签名固定为:template void serialize(Archive& ar)

立即学习C++免费学习笔记(深入)”;

例如:

struct Person {     std::string name;     int age = 0;      template     void serialize(Archive& ar) {         ar(CEREAL_NVP(name), CEREAL_NVP(age));     } };

CEREAL_NVP 是“命名变量包装器”,用于 JSON/XML 输出时保留字段名;二进制存档中可省略,直接写 ar(name, age) 也行。

若不想改类定义,也可用外部非成员函数(需声明为 friend 或放在同命名空间):

template void serialize(Archive& ar, Person& p) {     ar(CEREAL_NVP(p.name), CEREAL_NVP(p.age)); }

3. 选择存档类型并读写数据

Cereal 提供三种主流存档:

  • BinaryArchive:最快、体积最小,跨平台但不兼容不同字节序(通常本地用没问题)
  • JSONArchive:人类可读、跨语言友好,支持嵌套、注释(需开启宏),默认带字段名
  • XMLOutputArchive / XMLInputArchive:结构清晰,适合配置文件场景,但较冗余

写入示例(JSON):

std::ofstream os("person.json"); cereal::JSONOutputArchive ar(os); ar(CEREAL_NVP(p)); // p 是 Person 实例

读取示例(自动推导类型):

std::ifstream is("person.json"); cereal::JSONInputArchive ar(is); Person p2; ar(CEREAL_NVP(p2));

4. 处理常见情况的小技巧

容器与智能指针:std::vector、std::map、std::unique_ptr 等开箱即用,无需额外定义(只要元素类型可序列化)。

版本控制:用 CEREAL_class_VERSION(MyClass, 2) 声明版本,在 serialize 中用 ar(cereal::make_nvp("field", field)) + 条件逻辑做兼容。

忽略字段:用 cereal::make_nvp("ignored", cereal::binary_data(...)) 或更推荐——在 serialize 中跳过该字段(只读/写时条件判断)。

继承支持:基类需有虚析构函数,并在 serialize 中显式调用 ar(cereal::base_class(this))

基本上就这些。Cereal 不复杂但容易忽略细节:比如忘记加 template、误用 const 导致无法写入、或 JSON 读取前没检查文件是否存在。用熟之后,它比 Boost.Serialization 更清爽,比手写 JSON 解析更安全。

text=ZqhQzanResources