Ответ
Сериализация — это процесс преобразования объекта или структуры данных C++ в последовательность байтов или другой формат, пригодный для хранения (в файл, БД) или передачи (по сети). Десериализация — обратный процесс восстановления объекта из этого формата.
Зачем это нужно в C++ проектах:
- Сохранение и загрузка состояния: Конфигурации, игровые сохранения, кэш.
- Межпроцессное взаимодействие (IPC) и сетевое программирование: Передача сложных структур данных между приложениями или по сети (например, в gRPC, игровых серверах).
- Глубокое копирование объектов: Через сериализацию в память и последующую десериализацию.
Подходы и библиотеки в C++:
1. Ручная сериализация (для простых случаев):
#include <fstream>
struct Config {
int resolutionX;
int resolutionY;
bool fullscreen;
void save(const std::string& filename) const {
std::ofstream file(filename, std::ios::binary);
file.write(reinterpret_cast<const char*>(&resolutionX), sizeof(resolutionX));
file.write(reinterpret_cast<const char*>(&resolutionY), sizeof(resolutionY));
file.write(reinterpret_cast<const char*>(&fullscreen), sizeof(fullscreen));
}
void load(const std::string& filename) {
std::ifstream file(filename, std::ios::binary);
file.read(reinterpret_cast<char*>(&resolutionX), sizeof(resolutionX));
file.read(reinterpret_cast<char*>(&resolutionY), sizeof(resolutionY));
file.read(reinterpret_cast<char*>(&fullscreen), sizeof(fullscreen));
}
};
Недостатки: Не переносима (размер типов, порядок байт), не работает с полиморфизмом, сложна для вложенных структур.
2. Использование библиотек:
-
Текстовые форматы (человекочитаемые):
- JSON: Библиотеки
nlohmann/json,RapidJSON. Идеально для конфигов, веб-API.#include <nlohmann/json.hpp> using json = nlohmann::json;
struct Data { int id; std::string name; }; void to_json(json& j, const Data& d) { j = json{{"id", d.id}, {"name", d.name}}; } void from_json(const json& j, Data& d) { j.at("id").get_to(d.id); j.at("name").get_to(d.name); }
Data obj{1, "Test"}; json j = obj; // Сериализация в JSON строку std::string serialized = j.dump(); Data obj2 = j.get(); // Десериализация
- JSON: Библиотеки
-
Бинарные форматы (компактные и быстрые):
- Protocol Buffers (protobuf), FlatBuffers: Кросс-языковые, с предварительной компиляцией схемы (.proto файл). Очень эффективны для сетевого обмена.
- Boost.Serialization: Мощная, поддерживает полиморфизм, версионность, но добавляет зависимость от Boost.
- cereal: Заголовочная библиотека, похожая на Boost.Serialization, но без зависимостей от Boost.
#include <cereal/archives/binary.hpp> #include <cereal/types/string.hpp> #include <fstream>
struct MyData { int version; std::string message;
template <class Archive> void serialize(Archive& archive) { archive(version, message); // Одна функция для сериализации и десериализации }};
// Сериализация MyData data_out{2, "Hello Cereal"}; std::ofstream os("data.bin", std::ios::binary); cereal::BinaryOutputArchive archive_out(os); archive_out(data_out);
// Десериализация MyData data_in; std::ifstream is("data.bin", std::ios::binary); cereal::BinaryInputArchive archive_in(is); archive_in(data_in);
Критерии выбора: скорость, размер данных, необходимость человекочитаемости, поддержка схемы и версионности, кросс-языковость.
Видео-ответы
▶
▶
▶
▶
▶
▶
▶
▶
▶