Est-il possible de sérialiser et désérialiser une classe en C++?

est-il possible de sérialiser et de desérialiser une classe en C++?

J'utilise Java depuis 3 ans maintenant, et la sérialisation / deserialisation est assez triviale dans ce langage. Est-ce que C++ a des fonctionnalités similaires? Existe-il des bibliothèques natives que gérer la sérialisation?

Un exemple serait utile.

115
demandé sur Agusti-N 2008-10-24 22:19:42

11 réponses

la Boost::serialization la bibliothèque gère cela assez élégamment. Je l'ai utilisé dans plusieurs projets. Il y a un exemple de programme, montrant comment l'utiliser, ici .

la seule façon native de le faire est d'utiliser les cours d'eau. C'est essentiellement tout ce que fait la bibliothèque Boost::serialization , elle étend la méthode stream en mettant en place un framework pour écrire des objets à un format textuel et les lire à partir du même format.

pour les types intégrés, ou vos propres types avec operator<< et operator>> correctement définis, c'est assez simple; voir le C++ FAQ pour plus d'informations.

84
répondu Head Geek 2018-04-04 04:11:10

je me rends compte que c'est un vieux post mais c'est l'un des premiers qui apparaît lors de la recherche de c++ serialization .

j'encourage tous ceux qui ont accès à C++11 à jeter un oeil à cereal , une bibliothèque d'en-tête C++11 uniquement pour la sérialisation qui supporte binaire, JSON, et XML hors de la boîte. cereal a été conçu pour être facile à étendre et à utiliser et a une syntaxe similaire à Boost.

42
répondu Azoth 2014-03-02 01:00:53

Boost est une bonne suggestion. Mais si vous souhaitez lancer votre propre, il n'est pas difficile.

fondamentalement, vous avez juste besoin d'un moyen de construire un graphique d'objets et puis les produire à un certain format de stockage structuré (JSON, XML, YAML, peu importe). Construire le graphe est aussi simple que d'utiliser un algorithme de marquage récursif des objets décents et de sortir ensuite tous les objets marqués.

j'ai écrit un article décrivant un rudimentaire (mais encore puissant) sérialisation système. Vous pouvez le trouver intéressant: en utilisant SQLite comme un Format de fichier sur disque, Partie 2 .

15
répondu Frank Krueger 2011-04-02 18:16:28

je recommande Google tampons de protocole . J'ai eu la chance de tester la bibliothèque sur un nouveau projet et il est remarquablement facile à utiliser. La bibliothèque est fortement optimisé pour les performances.

Protobuf est différent des autres solutions de sérialisation mentionnées ici en ce sens qu'il ne sérialise pas vos objets, mais génère plutôt du code pour les objets qui sont sérialisation selon votre spécification.

13
répondu yoav.aviram 2008-10-24 21:04:25

Boost::serialization est une excellente option, mais j'ai rencontré un nouveau projet: Céréales que je trouve beaucoup plus élégant! Je vous suggère fortement d'enquêter sur elle.

11
répondu M2tM 2015-07-28 21:19:41

en ce qui concerne les bibliothèques" intégrées", les << et >> ont été réservées spécifiquement pour la sérialisation.

vous devez remplacer << pour afficher votre objet dans un contexte de sérialisation (habituellement un iostream ) et >> pour lire les données de ce contexte. Chaque objet est responsable de la sortie de ses objets enfants agrégés.

cette méthode fonctionne très bien tant que votre graphique objet ne contient pas cycle.

si c'est le cas, vous devrez utiliser une bibliothèque pour gérer ces cycles.

10
répondu Frank Krueger 2008-10-24 18:52:49

vous pouvez vérifier le protocole amef , un exemple d'encodage C++ dans amef serait comme,

    //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);

le décodage en java serait comme,

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

L'implémentation du protocole a des codecs pour C++ et Java, la partie intéressante est qu'il peut conserver la représentation de classe d'objet sous la forme de paires de valeurs de nom, J'ai tenu un protocole similaire dans mon dernier projet, quand j'ai d'ailleurs tombé sur ce protocole, j'avais en fait modifié la bibliothèque de base selon mes exigences. Espérons que cela vous aide.

4
répondu Dave 2011-06-04 06:30:22

je recommande d'utiliser la sérialisation boost comme décrit par d'autres affiches. Voici un bon tutoriel détaillé sur la façon de l'utiliser qui complète les tutoriels boost bien: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/

3
répondu jbat100 2012-11-29 11:04:10

Sweet Persist est un autre.

il est possible de sérialiser vers et depuis des flux en formats XML, JSON, Lua et binaire.

3
répondu Vincent 2014-09-05 01:57:38

je suggère d'examiner les usines abstraites qui sont souvent utilisées comme base pour la sérialisation

j'ai répondu à une autre question sur les usines C++. S'il vous plaît voir il si une usine flexible est d'intérêt. J'essaie de décrire une ancienne façon de ET++ d'utiliser des macros qui a très bien fonctionné pour moi.

et++ était un projet de portage de MacApp sur C++ et X11. Dans l'effort de Eric Gamma etc commencé à penser à modèles de conception . ET++ contenait des moyens automatiques de sérialisation et d'introspection à l'exécution.

2
répondu epatel 2017-05-23 11:54:46

si vous voulez des performances simples et meilleures et ne vous souciez pas de la compatibilité des données en arrière, essayez HPS , il est léger, beaucoup plus rapide que Boost, etc, et beaucoup plus facile à utiliser que Protobuf, etc.

exemple:

std::vector<int> data({22, 333, -4444});
std::string serialized = hps::serialize_to_string(data);
auto parsed = hps::parse_from_string<std::vector<int>>(serialized);
0
répondu streaver91 2017-12-29 14:29:34