C++ 对象序列化:库与方法

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C++ 对象序列化:工具与库概览



序列化是将复杂数据结构(对象、数组、图)转换为线性格式(字节流、JSON 字符串、XML)的过程,以便保存到文件、通过网络传输或写入数据库。逆向过程——反序列化——则恢复对象的原始状态。C++ 没有内置的反射支持(如 Java 或 Python),因此进行序列化时,要么手动编写代码,要么使用现成的库。本文将介绍 C++ 中最流行且高效的序列化工具。



1. Boost.Serialization



最古老且功能最强大的库。属于 Boost 库的一部分,需要单独安装。支持二进制、文本(XML)以及其自身的可移植归档格式。



  • 优点: 深度支持 STL、智能指针、多态、循环引用;版本控制;跨平台兼容性。
  • 缺点: 语法繁琐,编译速度慢,可执行文件体积大。


#include <boost/archive/text_oarchive.hpp>#include <boost/archive/text_iarchive.hpp>#include <boost/serialization/vector.hpp>#include <fstream>#include <vector>

struct Person { std::string name; int age; std::vector<std::string> tags;

template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & name; ar & age; ar & tags; }};

int main() { Person p{"Alice", 30, {"developer", "cpp"}}; std::ofstream ofs("person.txt"); boost::archive::text_oarchive oa(ofs); oa << p;

// 反序列化 Person restored; std::ifstream ifs("person.txt"); boost::archive::text_iarchive ia(ifs); ia >> restored; return 0;}


2. Cereal



一个现代、轻量级、仅头文件的库(无需编译)。支持 C++11 及以上版本。支持 JSON、XML 和二进制格式。在游戏行业和嵌入式开发中非常流行。



  • 优点: 开销最小,API 直观,支持智能指针、多态、STL 容器。
  • 缺点: 自定义能力不如 Boost。


#include <cereal/archives/json.hpp>#include <cereal/types/vector.hpp>#include <cereal/types/string.hpp>#include <sstream>

struct Person { std::string name; int age;

template<class Archive> void serialize(Archive & ar) { ar(CEREAL_NVP(name), CEREAL_NVP(age)); }};

int main() { Person p{"Bob", 25}; std::ostringstream oss; { cereal::JSONOutputArchive archive(oss); archive(CEREAL_NVP(p)); } std::cout << oss.str() << std::endl;

// 反序列化 Person restored; std::istringstream iss(oss.str()); { cereal::JSONInputArchive archive(iss); archive(restored); } return 0;}


3. nlohmann/json (JSON for Modern C++)



C++ 中最流行的 JSON 处理库。虽然最初并非为对象序列化设计,但可以通过自定义转换器(适配器模式)轻松适配。



  • 优点: 语法简单优雅,文档优秀,仅头文件,可与任何类型集成。
  • 缺点: 仅支持 JSON,不支持二进制格式,对于复杂对象图需要手动描述。


#include <nlohmann/json.hpp>#include <fstream>

using json = nlohmann::json;

struct Point { double x, y;

推荐