it-swarm.com.de

Ist es möglich, eine Klasse in C ++ zu serialisieren und zu deserialisieren?

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 Serialisierung handhaben?

Ein Beispiel wäre hilfreich.

130
Agusti-N

Das Boost::serialization Bibliothek behandelt dies ziemlich elegant. Ich habe es in mehreren Projekten verwendet. Es gibt ein Beispielprogramm, das zeigt, wie man es benutzt, hier .

Die einzige native Möglichkeit ist die Verwendung von Streams. Das ist im Wesentlichen alles Boost::serialization library erweitert die stream-Methode, indem ein Framework eingerichtet wird, mit dem Objekte in ein textähnliches Format geschrieben und aus demselben Format gelesen werden können.

Für eingebaute Typen oder Ihre eigenen Typen mit operator<< und operator>> richtig definiert, das ist ziemlich einfach; Siehe die C++ FAQ für weitere Informationen.

90
Head Geek

Mir ist klar, dass dies ein alter Beitrag ist, aber er ist einer der ersten, der bei der Suche nach c++ serialization Auftaucht.

Ich empfehle jedem, der Zugriff auf C++ 11 hat, sich cereal anzuschauen, eine C++ 11-Bibliothek nur für die Serialisierung, die standardmäßig Binär-, JSON- und XML-Dateien unterstützt. Cereal ist einfach zu erweitern und zu verwenden und hat eine ähnliche Syntax wie Boost.

47
Azoth

Boost ist ein guter Vorschlag. Aber wenn du deine eigenen würfeln möchtest, ist es nicht so schwer.

Grundsätzlich brauchen Sie nur eine Möglichkeit, ein Diagramm von Objekten zu erstellen und diese dann in einem strukturierten Speicherformat (JSON, XML, YAML, was auch immer) auszugeben. Das Erstellen des Graphen ist so einfach wie die Verwendung eines Algorithmus zum Markieren rekursiver anständiger Objekte und anschließendes 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 Dateiformat auf der Festplatte, Teil 2 .

16
Frank Krueger

Boost :: serialization ist eine großartige Option, aber ich habe ein neues Projekt entdeckt: Cereal was ich viel eleganter finde! Ich empfehle dringend, es zu untersuchen.

13
M2tM

Ich empfehle Google Protokollpuffer . Ich hatte die Möglichkeit, die Bibliothek in 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.

13
yoav.aviram

In Bezug auf "eingebaute" Bibliotheken sind << Und >> Speziell für die Serialisierung reserviert.

Sie sollten << Überschreiben, um Ihr Objekt in einem Serialisierungskontext (normalerweise ein iostream) auszugeben, und >>, Um Daten aus diesem Kontext zurückzulesen. Jedes Objekt ist für die Ausgabe seiner aggregierten untergeordneten Objekte verantwortlich.

Diese Methode funktioniert einwandfrei, solange Ihr Objektgraph keine Zyklen enthält.

Wenn dies der Fall ist, müssen Sie eine Bibliothek verwenden, um diese Zyklen zu verarbeiten.

12
Frank Krueger

Sie können das Protokoll amef überprüfen. Ein Beispiel für die C++ - Codierung in amef wäre:

    //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);

Dekodierung in Java wäre wie,

    string arr = amef encoded byte array value;
    AMEFDecoder decoder = new AMEFDecoder()
    AMEFObject object1 = AMEFDecoder.decode(arr,true);

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 auf dieses Protokoll gestoßen bin, das ich tatsächlich hatte änderte die Basisbibliothek nach meinen Anforderungen. Hoffe das hilft dir.

4
Dave

Ich empfehle die Verwendung der Boost-Serialisierung, wie auf anderen Postern beschrieben. Hier ist ein ausführliches Tutorial, das die Boost-Tutorials gut ergänzt: http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c- Serialisierung /

3
jbat100

Sweet Persist ist eine andere.

Es ist möglich, zu und von Streams in den Formaten XML, JSON, Lua und Binär zu serialisieren.

3
Vincent

Ich schlage vor, abstrakte Fabriken zu untersuchen, die häufig als Grundlage für die Serialisierung dienen

Ich habe in einer anderen SO Frage zu C++ - Fabriken. Bitte lesen Sie dort , wenn eine flexible Factory von Interesse ist. Ich versuche, eine alte Methode von ET ++ zur Verwendung von Makros zu beschreiben das hat bei mir super geklappt.

ET ++ war ein Projekt zur Portierung alter MacApps auf C++ und X11. In dem Bemühen, es Eric Gamma usw. zu denken begann Design Patterns . ET ++ enthielt automatische Möglichkeiten zur Serialisierung und Introspektion zur Laufzeit.

2
epatel

Wenn Sie eine einfache und optimale Leistung wünschen und sich nicht für die Abwärtskompatibilität von Daten interessieren, versuchen Sie HPS , es ist leichtgewichtig, viel schneller als Boost usw. und viel einfacher zu benutzen als Protobuf, etc.

Beispiel:

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);
0
streaver91