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.
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.
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.
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 .
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.
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.
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.
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.
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/
Sweet Persist est un autre.
il est possible de sérialiser vers et depuis des flux en formats XML, JSON, Lua et binaire.
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.
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);