Skip to content

cereal — 序列化库

cereal 是 C++11 的头文件序列化库,支持 JSON、XML、二进制格式,API 极其简洁,只需一个 serialize 函数。

安装

bash
vcpkg install cereal
# 或直接下载头文件:https://github.com/USCiLab/cereal

基本序列化

cpp
#include <cereal/archives/json.hpp>
#include <cereal/archives/binary.hpp>
#include <cereal/archives/xml.hpp>
#include <cereal/types/vector.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/map.hpp>

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

    // 一个函数搞定序列化和反序列化
    template<class Archive>
    void serialize(Archive& ar) {
        ar(CEREAL_NVP(name),    // NVP = Name-Value Pair(JSON/XML 中显示字段名)
           CEREAL_NVP(age),
           CEREAL_NVP(hobbies));
    }
};

// JSON 序列化
Person p{"Alice", 30, {"reading", "coding"}};

std::ostringstream oss;
{
    cereal::JSONOutputArchive archive(oss);
    archive(cereal::make_nvp("person", p));
}
std::cout << oss.str() << "\n";

// JSON 反序列化
std::istringstream iss(oss.str());
Person p2;
{
    cereal::JSONInputArchive archive(iss);
    archive(cereal::make_nvp("person", p2));
}

// 二进制序列化(最快,最小)
std::ofstream os("data.bin", std::ios::binary);
{
    cereal::BinaryOutputArchive archive(os);
    archive(p);
}

std::ifstream is("data.bin", std::ios::binary);
{
    cereal::BinaryInputArchive archive(is);
    archive(p2);
}

继承与多态

cpp
#include <cereal/types/polymorphic.hpp>

struct Shape {
    virtual ~Shape() = default;
    virtual double area() const = 0;

    template<class Archive>
    void serialize(Archive& ar) {}
};

struct Circle : Shape {
    double radius;
    double area() const override { return 3.14159 * radius * radius; }

    template<class Archive>
    void serialize(Archive& ar) {
        ar(cereal::base_class<Shape>(this), CEREAL_NVP(radius));
    }
};

// 注册多态类型
CEREAL_REGISTER_TYPE(Circle)

// 序列化多态指针
std::shared_ptr<Shape> shape = std::make_shared<Circle>();
static_cast<Circle*>(shape.get())->radius = 5.0;

std::ostringstream oss;
{
    cereal::JSONOutputArchive ar(oss);
    ar(shape);
}

关键认知

cereal 的核心优势是一个 serialize 函数同时处理序列化和反序列化,代码量极少。二进制格式性能最好,JSON/XML 格式可读性好。对于高性能场景,考虑 FlatBuffers 或 Protocol Buffers。

系统学习 C++ 生态,深入底层架构