Est-il possible de sérialiser et désérialiser une classe en C ++?
J'utilise Java depuis 3 ans maintenant, et la sérialisation / désérialisation est assez triviale 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.
c++
serialization
Agusti-N
la source
la source
Réponses:
La
Boost::serialization
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 des flux. C'est essentiellement tout ce que fait la
Boost::serialization
bibliothèque, elle étend la méthode de flux en configurant 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<<
etoperator>>
correctement définis, c'est assez simple; consultez la FAQ C ++ pour plus d'informations.la source
Je me rends compte que c'est un ancien post, mais c'est l'un des premiers qui apparaît lors de la recherche
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 uniquement pour la sérialisation qui prend en charge binaire, JSON et XML prêt à l'emploi. cereal a été conçu pour être facile à étendre et à utiliser et a une syntaxe similaire à Boost.
la source
Boost est une bonne suggestion. Mais si vous souhaitez rouler vous-même, ce n'est pas si difficile.
Fondamentalement, vous avez juste 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 d'objet décent récursif de marquage, 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 pouvez trouver cela intéressant: Utilisation de SQLite comme format de fichier sur disque, partie 2 .
la source
En ce qui concerne les bibliothèques "intégrées", les
<<
et>>
ont été réservés spécifiquement pour la sérialisation.Vous devez remplacer
<<
pour afficher votre objet dans un contexte de sérialisation (généralement uniostream
) et>>
pour lire les données à partir de ce contexte. Chaque objet est responsable de la sortie de ses objets enfants agrégés.Cette méthode fonctionne correctement tant que votre graphique d'objets ne contient aucun cycle.
Si c'est le cas, vous devrez utiliser une bibliothèque pour gérer ces cycles.
la source
<<
opérateurs implémentés sont utilisés pour imprimer des représentations textuelles d'objets lisibles par l'homme, ce qui n'est très souvent pas ce que vous voulez pour la sérialisation.<<
pour le génériqueostream
, essayez de le définir pour un flux de fichiers.<<
pour sortir votre objet dans un contexte de sérialisation… Chaque objet est responsable de la sortie de son…» - la question est de savoir comment éviter d'avoir à écrire cela laborieusement pour chaque objet: à quel point le aide à la langue ou aux bibliothèques?Je recommande les tampons de protocole Google . J'ai eu la chance de tester la bibliothèque sur un nouveau projet et c'est remarquablement facile à utiliser. La bibliothèque est fortement optimisée pour les performances.
Protobuf est différent des autres solutions de sérialisation mentionnées ici dans le sens où il ne sérialise pas vos objets, mais génère plutôt du code pour les objets qui sont sérialisés selon vos spécifications.
la source
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 de l'étudier.
la source
Vous pouvez vérifier le protocole amef , un exemple d'encodage C ++ dans amef serait comme,
Le décodage en java serait comme,
L'implémentation du protocole a des codecs pour C ++ et Java, la partie intéressante est qu'elle peut conserver la représentation de la classe d'objet sous la forme de paires de valeurs de nom, j'avais besoin d'un protocole similaire dans mon dernier projet, quand je suis tombé par hasard sur ce protocole, j'avais en fait modifié la bibliothèque de base selon mes besoins. J'espère que cela vous aide.
la source
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 bien les tutoriels boost: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/
la source
Sweet Persist en est un autre.
Il est possible de sérialiser vers et depuis des flux aux formats XML, JSON, Lua et binaires.
la source
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 SO sur les usines C ++. Veuillez y voir si une usine flexible présente un intérêt. J'essaie de décrire une ancienne méthode d'ET ++ pour utiliser des macros qui a très bien fonctionné pour moi.
ET ++ était un projet de portage de l'ancien MacApp vers C ++ et X11. Dans cet effort, Eric Gamma, etc. a commencé à réfléchir aux modèles de conception . ET ++ contenait des moyens automatiques de sérialisation et d'introspection lors de l'exécution.
la source
Si vous voulez des performances simples et optimales et que vous ne vous souciez pas de la compatibilité ascendante des données, essayez HPS , il est léger, beaucoup plus rapide que Boost, etc., et beaucoup plus facile à utiliser que Protobuf, etc.
Exemple:
la source
Voici une bibliothèque de sérialiseur simple que j'ai créée. C'est l'en-tête uniquement, c11 et contient des exemples pour la sérialisation des types de base. En voici une pour une carte en classe.
https://github.com/goblinhack/simple-c-plus-plus-serializer
Production:
la source
J'utilise le modèle suivant pour implémenter la sérialisation:
Voici
T
le type que vous souhaitez sérialiserMode
est un type factice pour différencier les différents types de sérialisation, par exemple. le même entier peut être sérialisé en tant que little endian, big endian, varint, etc.Par défaut,
Serializer
délègue la tâche à l'objet en cours de sérialisation. Pour les types intégrés, vous devez créer une spécialisation de modèle duSerializer
.Des modèles de fonctions pratiques sont également fournis.
Par exemple, la sérialisation little endian d'entiers non signés:
Puis pour sérialiser:
Pour désérialiser:
En raison de la logique de l'itérateur abstrait, il devrait fonctionner avec n'importe quel itérateur (par exemple, les itérateurs de flux), pointeur, etc.
la source