Ist es möglich, eine Klasse in C++ zu serialisieren und zu deserialisieren?
Lesezeit: 6 Minuten
Ist es möglich, eine Klasse in C++ zu serialisieren und zu deserialisieren?
Ich benutze Java jetzt seit 3 Jahren und Serialisierung / Deserialisierung ist in dieser Sprache ziemlich trivial. Hat C++ ähnliche Funktionen? Gibt es native Bibliotheken, die die Serialisierung handhaben?
Ein Beispiel wäre hilfreich.
nicht sicher, was Sie mit “nativ” meinen, meinen Sie natives C++ (wie Boost.Serialization)? Meinen Sie damit, nur die C++-Standardbibliothek zu verwenden? Meinst du etwas anderes?
– jwfear
24. Oktober 2008 um 18:54 Uhr
ich meine “keine externe Software-Bibliothek”. Und sorry, mein Englisch ist nicht sehr gut :S. Ich komme aus Argentinien
– Agusti-N
24. Oktober 2008 um 19:04 Uhr
Es gibt keine native Möglichkeit, ein Objekt zu serialisieren (Sie können die Binärdaten immer noch von einem POD ausgeben, aber Sie erhalten nicht das, was Sie wollen). Dennoch ist Boost, obwohl es keine „interne Bibliothek“ ist, die erste externe Bibliothek, die Sie Ihrem Compiler hinzufügen sollten. Boost ist von STL-Qualität (dh Top Gun C++)
– Paercebal
24. Oktober 2008 um 21:28 Uhr
Kopf Geek
Die Boost::serialization Die Bibliothek handhabt dies ziemlich elegant. Ich habe es in mehreren Projekten verwendet. Es gibt ein Beispielprogramm, das zeigt, wie man es benutzt, Hier.
Der einzige native Weg, dies zu tun, ist die Verwendung von Streams. Das ist im Wesentlichen alles Boost::serialization Die Bibliothek 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 eingebaute Typen oder Ihre eigenen Typen mit operator<< und operator>> richtig definiert, das ist ziemlich einfach; sehen die C++-FAQ für mehr Informationen.
Es scheint mir, dass boost::serialization erfordert, dass der Aufrufer die Reihenfolge verfolgt, in der Objekte geschrieben und gelesen werden. Ist das korrekt? Wenn es also eine Änderung in der Reihenfolge gibt, in der zwei Felder zwischen Versionen eines Programms geschrieben werden, dann haben wir eine Inkompatibilität. Ist das richtig?
– Agnel Kurian
2. Juli 2013 um 8:19 Uhr
Das liegt wahrscheinlich an den Serialisierungsfunktionen, nicht am Boost::serialization-Code selbst.
– Kopf Geek
7. September 2013 um 14:39 Uhr
@0xDEADBEEF: Das ist wahrscheinlich bei der Verwendung eines Binär_(i|o)-Archivs passiert, das andere “Probleme” wie Endian-ness einführt. Probieren Sie text_(i|o)archive aus, es ist plattformunabhängiger.
– Ela782
26. Dezember 2014 um 22:23 Uhr
Eine spezifische Framework-/Bibliothekslösung sollte nicht die akzeptierte Antwort sein.
– Andreas
1. März 2016 um 12:49 Uhr
@Andrea: Die Boost-Bibliothek ist ein Sonderfall. Bis zur Fertigstellung von C++11 war es so gut wie unmöglich, modernen C++-Code ohne C++ zu schreiben, sodass es eher einer sekundären STL als einer separaten Bibliothek ähnelte.
– Kopf Geek
1. März 2016 um 13:56 Uhr
Mir ist klar, dass dies ein alter Beitrag ist, aber er ist einer der ersten, der bei der Suche nach auftaucht c++ serialization.
Ich ermutige jeden, der Zugriff auf C++11 hat, einen Blick darauf zu werfen Getreide, eine reine C++11-Header-Bibliothek für die Serialisierung, die binäre, JSON- und XML-Dateien standardmäßig unterstützt. Cerealien wurde so konzipiert, dass es einfach zu erweitern und zu verwenden ist und eine ähnliche Syntax wie Boost hat.
Das Gute an Müsli ist, dass es im Gegensatz zu Boost nur minimale Metadaten hat (fast keine). boost::serialization wird wirklich lästig, wenn es jedes Mal, wenn Sie ein Archiv öffnen, seine lib-Version in den Stream schreibt, was das Anhängen an eine Datei unmöglich macht.
– Terry Shi
5. August 2014 um 5:52 Uhr
@CyberSnoopy – es gibt ein Flag zum Unterdrücken dieser Funktion, wenn ein Archiv erstellt wird – natürlich müssen Sie es auch beim Lesen des Archivs beachten.
– Robert Ramey
30. November 2016 um 20:37 Uhr
Frank Krüger
Boost ist ein guter Vorschlag. Aber wenn Sie Ihre eigenen rollen möchten, ist es nicht so schwer.
Im Grunde brauchen Sie nur eine Möglichkeit, ein Diagramm von Objekten zu erstellen und sie dann in einem strukturierten Speicherformat (JSON, XML, YAML, was auch immer) auszugeben. Das Erstellen des Diagramms ist so einfach wie die Verwendung eines markierenden rekursiven Algorithmus für anständige Objekte und das anschließende Ausgeben aller markierten Objekte.
Soweit “eingebaute” Bibliotheken gehen, die << und >> wurden speziell für die Serialisierung reserviert.
Sie sollten überschreiben << um Ihr Objekt in einem Serialisierungskontext auszugeben (normalerweise eine iostream) und >> um Daten aus diesem Kontext zurückzulesen. Jedes Objekt ist für die Ausgabe seiner aggregierten untergeordneten Objekte verantwortlich.
Diese Methode funktioniert gut, solange Ihr Objektdiagramm keine Zyklen enthält.
Wenn dies der Fall ist, müssen Sie eine Bibliothek verwenden, um mit diesen Zyklen umzugehen.
Ich empfehle Google Protokollpuffer. Ich hatte die Gelegenheit, die Bibliothek in einem neuen Projekt zu testen, und sie ist bemerkenswert einfach zu bedienen. Die Bibliothek ist stark auf Leistung optimiert.
Protobuf unterscheidet sich von anderen hier erwähnten Serialisierungslösungen insofern, als es Ihre Objekte nicht serialisiert, sondern Code für Objekte generiert, die gemäß Ihrer Spezifikation serialisiert werden.
Haben Sie damit Erfahrung beim Serialisieren von Objekten mit einer Größe von etwa 10-50 MB? Die Dokumentation scheint zu besagen, dass Protokollpuffer am besten für Objekte mit einer Größe von etwa einem MB geeignet sind.
Boost::Serialisierung ist eine großartige Option, aber ich bin auf ein neues Projekt gestoßen: Getreide was ich viel eleganter finde! Ich empfehle dringend, es zu untersuchen.
Haben Sie damit Erfahrung beim Serialisieren von Objekten mit einer Größe von etwa 10-50 MB? Die Dokumentation scheint zu besagen, dass Protokollpuffer am besten für Objekte mit einer Größe von etwa einem MB geeignet sind.
Sie können die überprüfen amef Protokoll, wäre ein Beispiel für C++-Codierung in amef wie folgt:
//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);
Die Protokollimplementierung hat Codecs für C++ und Java, der interessante Teil ist, dass sie die Objektklassendarstellung in Form von Name-Wert-Paaren beibehalten kann, ich benötigte ein ähnliches Protokoll in meinem letzten Projekt, als ich zufällig über dieses Protokoll stolperte, hatte ich tatsächlich modifizierte die Basisbibliothek nach meinen Anforderungen. Hoffe das hilft dir.
9973100cookie-checkIst es möglich, eine Klasse in C++ zu serialisieren und zu deserialisieren?yes
nicht sicher, was Sie mit “nativ” meinen, meinen Sie natives C++ (wie Boost.Serialization)? Meinen Sie damit, nur die C++-Standardbibliothek zu verwenden? Meinst du etwas anderes?
– jwfear
24. Oktober 2008 um 18:54 Uhr
ich meine “keine externe Software-Bibliothek”. Und sorry, mein Englisch ist nicht sehr gut :S. Ich komme aus Argentinien
– Agusti-N
24. Oktober 2008 um 19:04 Uhr
Es gibt keine native Möglichkeit, ein Objekt zu serialisieren (Sie können die Binärdaten immer noch von einem POD ausgeben, aber Sie erhalten nicht das, was Sie wollen). Dennoch ist Boost, obwohl es keine „interne Bibliothek“ ist, die erste externe Bibliothek, die Sie Ihrem Compiler hinzufügen sollten. Boost ist von STL-Qualität (dh Top Gun C++)
– Paercebal
24. Oktober 2008 um 21:28 Uhr