2016-08-02 10 views
-1

Ich versuche zu lernen, wie C++ - Objekte zu serialisieren. Nach dem Lesen von ein paar Posts hier, scheint es eine gute Idee zu verwenden boost Serialisierungsfunktionen und Archivierung mit Lade/Speichern-Funktionen. Allerdings möchte ich die Boost-Bibliothek vermeiden.Serialize C++ - Objekt, ohne seine Felder zu kennen

Konzeptionell kann ich ein Objekt speichern, ohne seine Felder zu kennen. Ohne Reflexion in C++ ist die einzige Möglichkeit, ein Objekt zu speichern, die Kenntnis aller seiner Klassenmitglieder.

Kann stringstream verwenden und den Operator << überladen, um ein Objekt in eine Zeichenfolge zu konvertieren, kann ich ein Objekt direkt speichern.

Danke, K.

+2

Nein. In einer Sprache ohne Nachdenken können Sie mit den Mitgliedern nichts anfangen, wenn Sie nicht wissen, was diese Mitglieder sind. –

+1

Jemand muss seine Felder kennen, möglicherweise selbst. Sie können es so einrichten, dass der Aufrufer die Felder nicht kennen muss und dass es eine Funktion zum Lesen und Schreiben gibt. Beachten Sie, dass die Serialisierung viele heikle Probleme hat, wie Versionsverwaltung und dergleichen, die Bibliotheken, die alle für eine bestimmte Größe geeignet sind, in Frage stellen. – Yakk

Antwort

1

Konzeptionell kann ich sparen, ein Objekt ohne seine Felder zu kennen.

Nein, das geht nicht.

Ohne Reflexion in C++, ist die einzige Möglichkeit, ein Objekt zu speichern, die Kenntnis aller seiner Klassenmitglieder.

Ja. Der beste Weg ist, dass das Wissen in dieser Klasse selbst eingekapselt zu verlassen:

class MyClass { 
public: 
    std::ostream& put(std::ostream& os) const { 
     os << field1 << " " << field2 << std::endl; 
     return os; 
    } 
    friend std::ostream& operator<<(std::ostream& os, const MyClass& myclass) { 
     return myClass.put(os); 
    } 
private: 
    int field1; 
    double field2; 
}; 
+0

Ich mag dieses Design nicht, weil gelesenes Schreiben trocken verletzt. Fügen Sie eine Hilfsvorlage hinzu und haben Sie eine Funktion beim Lesen der Version lesen und Schreiben der Version schreiben, um die Dinge zu verbessern. – Yakk

+0

@Yakk Sie können immer mehr Ebenen der Indirection hinzufügen, was Sie nicht daran hindert, die tatsächlichen Felder zu kennen (hier QED). –

+0

Dies wird sehr schnell kompliziert (zB vorstellen, wenn die Klasse ein String-Feld hatte) - ich denke, es wäre besser zu implementieren put durch Aufruf einer Hilfsfunktion für jedes benannte Mitglied, und der Helfer ist überlastet, um welche Mitgliedstypen Sie zu unterstützen wird –

0

Ein Ansatz, den Sie Tupel-likes und Iterables folgen können, ist standardmäßig zu unterstützen.

Haben Sie einen read_archive und write_archive die erste Phantasie sfinae tut Typen zu erkennen, die for(:) Schleifen und Typen unterstützen, die sie unterstützen std::tuple_size und ADL get<I>, dass Tupel-like sind.

Dies richtet sich auch mit einer Form der strukturierten Bindung Unterstützung in C++ 17.

Als nächstes haben Sie eine to_tie sfinae adl aktiviert basierte Implementierung, die to_tie() und to_tie(.) überprüft. Wenn ja und lesen/schreiben, verwendet das.

Vielleicht irgendwo darin enthalten ein Adl Lookup einer archive_io Funktion, so dass Sie explizit Ihre eigene io schreiben können.

Das Ziel ist es, so viel wie möglich automatisch zu archivieren, und was Sie nicht leicht zu komponieren können.