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;