Можно ли сериализовать и десериализовать класс в C ++? - PullRequest
128 голосов
/ 24 октября 2008

Можно ли сериализовать и десериализовать класс в C ++?

Я использую Java уже 3 года, и сериализация / десериализация на этом языке довольно тривиальна. Есть ли в C ++ похожие функции? Существуют ли нативные библиотеки, которые обрабатывают сериализацию?

Пример будет полезен.

Ответы [ 11 ]

90 голосов
/ 24 октября 2008

Библиотека Boost::serialization справляется с этим довольно элегантно. Я использовал это в нескольких проектах. Вот пример программы, показывающей, как ее использовать, здесь .

Единственный родной способ сделать это - использовать потоки. По сути, это все, что делает библиотека Boost::serialization, она расширяет потоковый метод, устанавливая платформу для записи объектов в текстоподобный формат и чтения их из того же формата.

Для встроенных типов или ваших собственных типов с правильно определенными operator<< и operator>> это довольно просто; см. FAQ по C ++ для получения дополнительной информации.

46 голосов
/ 02 марта 2014

Я понимаю, что это старый пост, но он один из первых, который появляется при поиске c++ serialization.

Я призываю всех, кто имеет доступ к C ++ 11, взглянуть на cereal , библиотеку C ++ 11 только для заголовков для сериализации, которая поддерживает двоичные файлы, JSON и XML из коробки. cereal был спроектирован так, чтобы его можно было легко расширять и использовать, и его синтаксис похож на Boost.

15 голосов
/ 24 октября 2008

Повышение является хорошим предложением. Но если вы хотите сделать свой собственный ролл, это не так сложно.

По сути, вам просто нужен способ построить график объектов и затем вывести их в какой-либо структурированный формат хранения (JSON, XML, YAML, что угодно). Построить график так же просто, как использовать алгоритм маркировки рекурсивного достойного объекта и затем вывести все отмеченные объекты.

Я написал статью, описывающую элементарную (но все еще мощную) систему сериализации. Вам может быть интересно: Использование SQLite в качестве файлового формата на диске, часть 2 .

13 голосов
/ 19 января 2013

Boost :: serialization - отличный вариант, но я столкнулся с новым проектом: Cereal , который я считаю гораздо более элегантным! Я настоятельно рекомендую исследовать это.

13 голосов
/ 25 октября 2008

Я рекомендую Google протокол буфера . У меня была возможность протестировать библиотеку в новом проекте, и она удивительно проста в использовании. Библиотека сильно оптимизирована для производительности.

Protobuf отличается от других упомянутых здесь решений для сериализации тем, что он не сериализует ваши объекты, а генерирует код для объектов, которые сериализуются в соответствии с вашей спецификацией.

11 голосов
/ 24 октября 2008

Что касается "встроенных" библиотек, то << и >> были зарезервированы специально для сериализации.

Вы должны переопределить << для вывода вашего объекта в некоторый контекст сериализации (обычно iostream) и >> для чтения данных из этого контекста. Каждый объект отвечает за вывод своих агрегированных дочерних объектов.

Этот метод работает нормально, если в вашем графе объектов нет циклов.

Если это произойдет, вам придется использовать библиотеку для обработки этих циклов.

4 голосов
/ 04 июня 2011

Вы можете проверить протокол amef , пример кодирования C ++ в amef будет выглядеть так:

    //Create a new AMEF object
    AMEFObject *object = new AMEFObject();

    //Add a child string object
    object->addPacket("This is the Automated Message Exchange Format Object property!!","adasd");   

    //Add a child integer object
    object->addPacket(21213);

    //Add a child boolean object
    object->addPacket(true);

    AMEFObject *object2 = new AMEFObject();
    string j = "This is the property of a nested Automated Message Exchange Format Object";
    object2->addPacket(j);
    object2->addPacket(134123);
    object2->addPacket(false);

    //Add a child character object
    object2->addPacket('d');

    //Add a child AMEF Object
    object->addPacket(object2);

    //Encode the AMEF obejct
    string str = new AMEFEncoder()->encode(object,false);

Декодирование в java было бы похоже на

    string arr = amef encoded byte array value;
    AMEFDecoder decoder = new AMEFDecoder()
    AMEFObject object1 = AMEFDecoder.decode(arr,true);

Реализация протокола имеет кодеки как для C ++, так и для Java, интересная часть в том, что она может сохранять представление класса объекта в виде пар имя-значение, Мне понадобился аналогичный протокол в моем последнем проекте, когда я случайно наткнулся на этот протокол, я фактически изменил базовую библиотеку в соответствии с моими требованиями. Надеюсь, это поможет вам.

3 голосов
/ 05 сентября 2014

Sweet Persist - еще один.

Существует возможность сериализации в и из потоков в XML, JSON, Lua и двоичных форматах.

3 голосов
/ 29 ноября 2012

Я рекомендую использовать сериализацию Boost, как описано другими авторами. Вот хороший подробный урок о том, как его использовать, который прекрасно дополняет уроки буста: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/

2 голосов
/ 02 апреля 2011

Я предлагаю рассмотреть абстрактные фабрики, которые часто используются в качестве основы для сериализации

Я ответил на другой вопрос о фабриках C ++. Пожалуйста, посмотрите там , если интерес представляет гибкая фабрика. Я пытаюсь описать старый способ из ET ++ для использования макросов, который отлично сработал для меня.

ET ++ был проектом по переносу старого MacApp на C ++ и X11. Для этого Эрик Гамма и другие начали думать о Design Patterns . ET ++ содержал автоматические способы сериализации и самоанализа во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...