Какие подходы и библиотеки для сериализации данных существуют в C++?

«Какие подходы и библиотеки для сериализации данных существуют в C++?» — вопрос из категории Архитектура, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Сериализация в C++ — это преобразование объектов или структур данных в формат, пригодный для хранения или передачи. Выбор подхода зависит от требований к скорости, размеру, читаемости и совместимости.

  1. Ручная (наивная) сериализация Прямая запись бинарных данных объектов в поток. Быстро и компактно, но хрупко: любые изменения в структуре класса ломают совместимость. Подходит для временного хранения или обмена данными внутри одной версии программы.

    struct Point { int x, y; };
    std::ofstream file("data.bin", std::ios::binary);
    Point p{10, 20};
    file.write(reinterpret_cast<const char*>(&p), sizeof(p));
  2. Библиотеки сериализации

    • Boost.Serialization: Мощная, гибкая библиотека. Поддерживает бинарный, текстовый и XML форматы, версионность, указатели на полиморфные объекты.
      #include <boost/archive/text_oarchive.hpp>
      #include <sstream>
      class MyClass { /*...*/ };
      // ...
      std::ostringstream oss;
      boost::archive::text_oarchive ar(oss);
      MyClass obj;
      ar << obj; // Сериализация
    • Cereal: Современная, header-only альтернатива Boost.Serialization с похожим синтаксисом.
  3. Структурированные форматы с кодогенерацией

    • Protocol Buffers (protobuf): Бинарный формат от Google. Вы определяете структуру данных в .proto-файле, компилятор генерирует классы C++ для сериализации/десериализации. Очень эффективен по размеру и скорости, обеспечивает обратную и прямую совместимость.
      // person.proto
      message Person {
        required string name = 1;
        optional int32 id = 2;
      }
    • FlatBuffers: Бинарный формат от Google, где данные хранятся в формате, готовом для чтения без парсинга/распаковки (zero-copy). Идеален для высокопроизводительных сценариев (игры, встраиваемые системы).
  4. Текстовые форматы (удобные для человека и веба)

    • JSON: Используется повсеместно в веб-API. Популярные библиотеки: nlohmann/json (header-only, очень удобный API), RapidJSON (высокая производительность).
      #include <nlohmann/json.hpp>
      nlohmann::json j;
      j["name"] = "Alice";
      j["age"] = 30;
      std::string serialized = j.dump(); // "{"name":"Alice","age":30}"
    • XML: Более строгий и verbose формат. Библиотеки: pugixml (быстрая), TinyXML-2. Часто требуется в корпоративных или legacy-системах.

Рекомендация по выбору: Для внутреннего RPC или хранения — protobuf. Для конфигураций или веб-API — JSON. Для максимальной производительности в памяти — FlatBuffers. Для сложных графов объектов с полиморфизмом — Boost.Serialization.