Сериализация объектов в 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

Современная, лёгкая, header-only библиотека (не требует сборки). Работает с C++11 и выше. Поддерживает JSON, XML и бинарные форматы. Очень популярна в игровой индустрии и embedded-разработке.

  • Преимущества: минимальные накладные расходы, интуитивный 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++)

Самая популярная библиотека для работы с JSON в C++. Хотя изначально не предназначена для сериализации объектов, её можно легко адаптировать с помощью пользовательских преобразователей (adapter pattern).

  • Преимущества: простой и красивый синтаксис, отличная документация, header-only, интеграция с любыми типами.
  • Недостатки: работает только с JSON, не поддерживает бинарные форматы, для сложных графов объектов требуется ручное описание.
#include <nlohmann/json.hpp>
#include <fstream>

using json = nlohmann::json;

struct Point {
    double x, y;
};

void to_json(json& j, const Point& p) {
    j = json{{"x", p.x}, {"y", p.y}};
}

void from_json(const json& j, Point& p) {
    p.x = j.at("x").get<double>();
    p.y = j.at("y").get<double>();
}

int main() {
    Point pt{3.14, 2.71};
    json j = pt;
    std::ofstream("point.json") << j.dump(4);

    // Десериализация
    std::ifstream ifs("point.json");
    json j2 = json::parse(ifs);
    Point restored = j2.get<Point>();
    return 0;
}

Рекомендаций