Est-il possible de sérialiser et de désérialiser une classe en C++?
J'utilise Java depuis 3 ans maintenant, et la sérialisation/désérialisation est assez simple dans ce langage. Le C++ a-t-il des fonctionnalités similaires? Existe-t-il des bibliothèques natives qui gèrent la sérialisation?
Un exemple serait utile.
Le Boost::serialization
La bibliothèque gère cela avec élégance. 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 des flux. C'est essentiellement tout le Boost::serialization
bibliothèque fait, il étend la méthode de flux en définissant un cadre pour écrire des objets dans un format de type texte et les lire à partir du même format.
Pour les types intégrés ou vos propres types avec operator<<
et operator>>
correctement défini, c'est assez simple; voir la FAQ C++ pour plus d'informations.
Je me rends compte qu’il s’agit d’un ancien message, mais c’est l’un des premiers articles qui apparaissent lors de la recherche de c++ serialization
.
J'encourage tous ceux qui ont accès à C++ 11 à jeter un œil à cereal , une bibliothèque d'en-tête C++ 11 pour la sérialisation prenant en charge binaire, JSON et XML. céréale a été conçue pour être facile à étendre et à utiliser et a une syntaxe similaire à celle de Boost.
Le boost est une bonne suggestion. Mais si vous voulez rouler le vôtre, ce n'est pas si difficile.
En gros, vous avez simplement besoin d’un moyen de créer un graphique d’objets, puis de les exporter dans un format de stockage structuré (JSON, XML, YAML, peu importe). Construire le graphique est aussi simple que d’utiliser un algorithme de marquage d’objet décent récursif, puis de sortir tous les objets marqués.
J'ai écrit un article décrivant un système de sérialisation rudimentaire (mais toujours puissant). Vous le trouverez peut-être intéressant: tilisation de SQLite comme format de fichier sur disque, partie 2 .
Boost :: serialization est une excellente option, mais j'ai rencontré un nouveau projet: Cereal que je trouve beaucoup plus élégant! Je suggère fortement d'enquêter.
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ée pour la performance.
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érialisés conformément à vos spécifications.
En ce qui concerne les bibliothèques "intégrées", la <<
et >>
ont été réservés spécifiquement pour la sérialisation.
Vous devriez remplacer <<
pour sortir votre objet dans un contexte de sérialisation (généralement un iostream
) et >>
pour relire les données de ce contexte. Chaque objet est responsable de la sortie de ses objets enfants agrégés.
Cette méthode fonctionne bien tant que votre graphe d'objets ne contient aucun 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 de codage C++ dans amef serait le suivant:
//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);
Décoder 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, ce qui est intéressant, c’est qu’elle peut conserver la représentation de la classe d’objet sous la forme de paires nom-valeur. J’avais donc eu besoin d’un protocole similaire dans mon dernier projet. modifié la bibliothèque de base selon mes besoins. J'espère que cela vous aide.
Je recommande d'utiliser la sérialisation boost telle que décrite par d'autres affiches. Voici un bon tutoriel détaillé sur son utilisation, qui complète bien les tutoriels de boost: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c- sérialisation /
Sweet Persist en est un autre.
Il est possible de sérialiser des flux vers et à partir de flux aux formats XML, JSON, Lua et binaire.
Je suggère de regarder dans les usines abstraites qui sont souvent utilisées comme base pour la sérialisation
J'ai répondu à une autre SO question sur les usines C++. Veuillez voir ici si une usine flexible est intéressante. J'essaie de décrire une ancienne méthode utilisée par ET ++ pour utiliser des macros ce qui a très bien fonctionné pour moi.
ET ++ était un projet visant à porter l'ancien MacApp en C++ et X11. Dans le cadre de cet effort, Eric Gamma etc. a commencé à réfléchir à Design Patterns . ET ++ contenait des moyens automatiques de sérialisation et d'introspection lors de l'exécution.
Si vous voulez des performances simples et optimales sans vous soucier de la compatibilité des données en amont, 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);