Ist es möglich, eine Klasse in C ++ zu serialisieren und zu deserialisieren?
Ich benutze Java seit 3 Jahren und Serialisierung / Deserialisierung ist in dieser Sprache ziemlich trivial. Hat C ++ ähnliche Funktionen? Gibt es native Bibliotheken, die die Serialisierung übernehmen?
Ein Beispiel wäre hilfreich.
c++
serialization
Agusti-N
quelle
quelle
Antworten:
Die
Boost::serialization
Bibliothek geht damit eher elegant um. Ich habe es in mehreren Projekten verwendet. Es gibt ein Beispielprogramm, das zeigt , wie es zu benutzen, hier .Die einzige native Möglichkeit besteht darin, Streams zu verwenden. Das ist im Wesentlichen alles, was die
Boost::serialization
Bibliothek tut. Sie erweitert die Stream-Methode, indem sie ein Framework zum Schreiben von Objekten in ein textähnliches Format und zum Lesen aus demselben Format einrichtet.Für integrierte Typen oder Ihre eigenen Typen mit
operator<<
undoperator>>
richtig definiert ist das ziemlich einfach. Weitere Informationen finden Sie in den C ++ - FAQ .quelle
Mir ist klar, dass dies ein alter Beitrag ist, aber er ist einer der ersten, der bei der Suche auftaucht
c++ serialization
.Ich empfehle jedem, der Zugriff auf C ++ 11 hat, einen Blick auf cereal zu werfen , eine C ++ 11-Header-Bibliothek für die Serialisierung, die sofort Binär-, JSON- und XML-Dateien unterstützt. Getreide wurde so konzipiert, dass es einfach zu erweitern und zu verwenden ist und eine ähnliche Syntax wie Boost hat.
quelle
Boost ist ein guter Vorschlag. Aber wenn Sie Ihre eigenen rollen möchten, ist es nicht so schwer.
Grundsätzlich benötigen Sie nur eine Möglichkeit, ein Diagramm von Objekten zu erstellen und diese dann in einem strukturierten Speicherformat (JSON, XML, YAML usw.) auszugeben. Das Erstellen des Diagramms ist so einfach wie das Verwenden eines markierungsrekursiven Algorithmus für anständige Objekte und das anschließende Ausgeben aller markierten Objekte.
Ich habe einen Artikel geschrieben, der ein rudimentäres (aber immer noch leistungsfähiges) Serialisierungssystem beschreibt. Vielleicht finden Sie es interessant: Verwenden von SQLite als On-Disk-Dateiformat, Teil 2 .
quelle
Was "eingebaute" Bibliotheken angeht, sind die
<<
und>>
speziell für die Serialisierung reserviert.Sie sollten überschreiben,
<<
um Ihr Objekt in einem Serialisierungskontext (normalerweise einemiostream
) auszugeben und>>
Daten aus diesem Kontext zurückzulesen. Jedes Objekt ist für die Ausgabe seiner aggregierten untergeordneten Objekte verantwortlich.Diese Methode funktioniert einwandfrei, solange Ihr Objektdiagramm keine Zyklen enthält.
Wenn dies der Fall ist, müssen Sie eine Bibliothek verwenden, um diese Zyklen zu verarbeiten.
quelle
<<
Operatoren werden verwendet, um von Menschen lesbare Textdarstellungen von Objekten zu drucken, was sehr oft nicht das ist, was Sie für die Serialisierung wollen.<<
das Generikum nicht für das Generikumostream
, sondern für einen Dateistream zu definieren.<<
um Ihr Objekt in einem Serialisierungskontext auszugeben ... Jedes Objekt ist für die Ausgabe seines ... verantwortlich." - Die Frage ist, wie Sie vermeiden können, dass Sie dies mühsam für jedes Objekt aufschreiben müssen: Wie viel kann das Sprache oder Bibliotheken helfen?Ich empfehle Google- Protokollpuffer . Ich hatte die Möglichkeit, die Bibliothek an einem neuen Projekt zu testen, und es ist bemerkenswert einfach zu bedienen. Die Bibliothek ist stark auf Leistung optimiert.
Protobuf unterscheidet sich von anderen hier erwähnten Serialisierungslösungen darin, dass es Ihre Objekte nicht serialisiert, sondern Code für Objekte generiert, die gemäß Ihrer Spezifikation serialisiert werden.
quelle
Boost :: Serialisierung ist eine großartige Option, aber ich bin auf ein neues Projekt gestoßen: Getreide, das ich viel eleganter finde! Ich empfehle dringend, es zu untersuchen.
quelle
Sie können das amef- Protokoll überprüfen . Ein Beispiel für die C ++ - Codierung in amef wäre wie folgt:
Dekodierung in Java wäre wie,
Die Protokollimplementierung enthält Codecs für C ++ und Java. Der interessante Teil ist, dass die Objektklassendarstellung in Form von Name-Wert-Paaren beibehalten werden kann. Ich habe in meinem letzten Projekt ein ähnliches Protokoll benötigt, als ich zufällig auf dieses Protokoll gestoßen bin, das ich tatsächlich hatte Die Basisbibliothek wurde gemäß meinen Anforderungen geändert. Hoffe das hilft dir.
quelle
Ich empfehle die Verwendung der Boost-Serialisierung, wie auf anderen Postern beschrieben. Hier ist ein gutes detailliertes Tutorial zur Verwendung, das die Boost-Tutorials gut ergänzt: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-serialization/
quelle
Süß bestehen ist eine andere.
Es ist möglich, zu und von Streams in den Formaten XML, JSON, Lua und Binär zu serialisieren.
quelle
Ich schlage vor, sich mit abstrakten Fabriken zu befassen, die häufig als Grundlage für die Serialisierung dienen
Ich habe in einer anderen SO-Frage zu C ++ - Fabriken geantwortet. Bitte sehen Sie dort, ob eine flexible Fabrik von Interesse ist. Ich versuche, einen alten Weg von ET ++ zu beschreiben, um Makros zu verwenden, der für mich großartig funktioniert hat.
ET ++ war ein Projekt, um alte MacApp auf C ++ und X11 zu portieren. In der Anstrengung begann Eric Gamma usw. über Designmuster nachzudenken . ET ++ enthielt automatische Möglichkeiten zur Serialisierung und Selbstbeobachtung zur Laufzeit.
quelle
Wenn Sie eine einfache und optimale Leistung wünschen und sich nicht um die Abwärtsdatenkompatibilität kümmern, versuchen Sie es mit HPS , das leichtgewichtig, viel schneller als Boost usw. und viel einfacher zu verwenden als Protobuf usw. ist.
Beispiel:
quelle
Hier ist eine einfache Serializer-Bibliothek, die ich aufgerissen habe. Es ist nur der Header c11 und enthält Beispiele für die Serialisierung von Basistypen. Hier ist eine für eine Karte zum Unterricht.
https://github.com/goblinhack/simple-c-plus-plus-serializer
Ausgabe:
quelle
Ich verwende die folgende Vorlage, um die Serialisierung zu implementieren:
Hier
T
ist der Typ, den Sie serialisieren möchten,Mode
ein Dummy-Typ, um zwischen verschiedenen Arten der Serialisierung zu unterscheiden, z. Die gleiche Ganzzahl kann als Little Endian, Big Endian, Varint usw. serialisiert werden.Standardmäßig
Serializer
delegiert die Aufgabe an das zu serialisierende Objekt. Für eingebaute Typen sollten Sie eine Vorlagenspezialisierung der vornehmenSerializer
.Vorlagen für Komfortfunktionen werden ebenfalls bereitgestellt.
Zum Beispiel Little-Endian-Serialisierung von Ganzzahlen ohne Vorzeichen:
Dann zu serialisieren:
Deserialisieren:
Aufgrund der abstrakten Iteratorlogik sollte es mit jedem Iterator (z. B. Stream-Iteratoren), Zeiger usw. funktionieren.
quelle