Objekte speichern sich selber oder werden gespeichert?
-
Mit Vererbung wäre ich eher vorsichtig, da man zum einen einen gewissen Overhead einführt und zum anderen weiß ich nicht ob man dadurch nicht mehr ausdrückt, als einem Lieb ist.
Ich finde den Ansatz von boost::serialization nicht schlecht
http://boost.org/libs/serialization/doc/index.htmlclass gps_position { private: friend class boost::serialization::access; // When the class Archive corresponds to an output archive, the // & operator is defined similar to <<. Likewise, when the class Archive // is a type of input archive the & operator is defined similar to >>. template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & degrees; ar & minutes; ar & seconds; } int degrees; int minutes; float seconds; public: gps_position(){}; gps_position(int d, int m, float s) : degrees(d), minutes(m), seconds(s) {} };
-
warum muss ..::access nochmal friend sein?
-
kurzefrage schrieb:
warum muss ..::access nochmal friend sein?
Vermutlich weil es auf
template<class Archive> void serialize(Archive & ar, const unsigned int version)zugreifen will, was in dem Fall private ist. Dürfte aber sicher nichts dagegen sprechen die Methode public zu machen.
-
ar & degrees; ar & minutes; ar & seconds;Ja, das ist Boost wie es "leibt und lebt". Unsinnige Operatorenüberladungen um dem nächsten Entwickler, der es lesen muss, eine kleine Überraschung zu bereiten. Wo kämen wir denn hin, wenn wir in Boost irgendwelche Schnittstellen im herkömmlichen Sinne verwenden.
Ich bin da eher für Gerards Ansatz und würde das Speichern abkoppeln.
public class Person { public String getName() { // ... } } public class PersonSerializer implements Serializer { private Person person = /* ... */ public void serialize() { serialize(person.getName()); } // ... }Bietet eben den Vorteil, dass man je nach Datentechnologie eine andere Form der Persistenz wählen kann (z.B: wird man kaum in eine Datenbank serialisieren, sondern eher auf Tabellen abbilden).
-
@boost`rockt:
Hat aber den Nachteil das ich keine internen Daten abspeichern kann.
Meine Objekte lasse ich lieber ein Saveable-Interface implementieren. Geladen werden die Objekte durch den Konstruktor.In Java könnte man auch private Daten speichern/laden durch Reflexion.
Aber der boost::serialization-Ansatz ist auch interessant. Aber wieso dann nicht gleich von boost::serialization::access erben und das void serialize()-Interface auf die übliche weise implementieren ?
Welche Vorteile bringt es einem zu verbergen das die Klasse Serialisation anbietet ?
In Java werden alle Klasse die Serialisation anbieten gekennzeichnet durch das Interface Serializable.Eine andere Möglichkeit in C++ wäre es, eine Klasse einfach den Operator << und >> anzubieten. << heist ja "schreibe in Stream" und >> heist "lese aus Stream".
Dann braucht man nur nochFileStream stream = new FileStream("mein_objekt.dat"); stream << mein_objekt; // speichern mein_objekt = new Mein_Objekt(stream); // laden
-
@boost`rockt:
Hat aber den Nachteil das ich keine internen Daten abspeichern kann.
Meine Objekte lasse ich lieber ein Saveable-Interface implementieren. Geladen werden die Objekte durch den Konstruktor.Interne Daten, die im normalen Programmablauf nicht verfügbar sein sollen, benötigt man doch ohnehin nur, wenn man auch Logik in diese Datenklassen verfrachtet und das mach ich ohnehin nicht (siehe z.B: XmlSerializer in .NET, die auch keine internen Daten beachten).
-
boost`rockt schrieb:
ar & degrees; ar & minutes; ar & seconds;Ja, das ist Boost wie es "leibt und lebt". Unsinnige Operatorenüberladungen um dem nächsten Entwickler, der es lesen muss, eine kleine Überraschung zu bereiten. Wo kämen wir denn hin, wenn wir in Boost irgendwelche Schnittstellen im herkömmlichen Sinne verwenden.
Wer die Funktion nicht versteht, hätte kein Programmierer werden sollen. Wobei die Überladung wirklich ein wenig sinnlos ist in dem Fall.
Bietet eben den Vorteil, dass man je nach Datentechnologie eine andere Form der Persistenz wählen kann (z.B: wird man kaum in eine Datenbank serialisieren, sondern eher auf Tabellen abbilden).
Bietet den Vorteil gegenüber welcher Lösung?
Persistenz ist übrigens mehr als Serialisierung
DEvent schrieb:
Aber der boost::serialization-Ansatz ist auch interessant. Aber wieso dann nicht gleich von boost::serialization::access erben und das void serialize()-Interface auf die übliche weise implementieren ?
weil serialize ein Template ist
Welche Vorteile bringt es einem zu verbergen das die Klasse Serialisation anbietet ?
(ot: warum machst du immer ein Leerzeichen vor dem Fragezeichen?)
Der Java Ansatz ist aus Java-Sicht sicherlich in Ordnung. Aber Vererbung bedeutet im C++-Sinn eben mehr. So fügt man einen vtable der Klasse hinzu etc.
Da ich keinen Vorteil darin sehe, eine Klasse von einer Serialize-Klasse zu erben, sehe ich kein Sinn darin das zu machen. In C++ geht man mit Vererbung nicht so inflazionär um, wie in .NET oder Java, weil man eben mehr Möglichkeiten hat.
In Java werden alle Klasse die Serialisation anbieten gekennzeichnet durch das Interface Serializable.
C++ ist nicht Java und es ist eine schlechte Idee C++ wie Java zu programmieren.
FileStream stream = new FileStream("mein_objekt.dat"); stream << mein_objekt; // speichern mein_objekt = new Mein_Objekt(stream); // laden*hust*
-
DEvent schrieb:
Eine andere Möglichkeit in C++ wäre es, eine Klasse einfach den Operator << und >> anzubieten. << heist ja "schreibe in Stream" und >> heist "lese aus Stream".
Dann braucht man nur noch...vielleicht noch den typ davorschreiben vor die objekte und beim lesen anhand des type den richtigen ctor aufrufen.
und mit den zeigern kanns böse enden. soll man die verfolgen? wenn nein, hat man beim reinladen nen zeiger ins nirvana. wenn ja, sollte man doppelverfolgungen und muß kreise verhindern.
-
rüdiger schrieb:
Wer die Funktion nicht versteht, hätte kein Programmierer werden sollen. Wobei die Überladung wirklich ein wenig sinnlos ist in dem Fall.
Der Operator macht in diesem Fall einfach keinen Sinn, da man & einfach nicht mit serialisieren in Verbindung bringt, wenn man es nicht weiß. Das hat nichts mit Unwissenheit des Programmierers zu tun. Aber ein derartiger "Fehler" ist in diesem Fall natürlich erlaubt, weil es um boost geht ..
rüdiger schrieb:
Bietet eben den Vorteil, dass man je nach Datentechnologie eine andere Form der Persistenz wählen kann (z.B: wird man kaum in eine Datenbank serialisieren, sondern eher auf Tabellen abbilden).
Bietet den Vorteil gegenüber welcher Lösung?
Persistenz ist übrigens mehr als Serialisierung
Genau meine Rede, Persistenz ist mehr als Serialisierung, und darum finde ich, dass eine Datenklasse auch nicht selbst entscheiden soll, welche Form der Persistenz verwendet wird (in deinem Fall eben serialisieren). Daher empfehle ich die Persistierung von der Datenklasse zu trennen um entsprechend Wahlmöglichkeiten zu besitzen, um auch z.B: die Daten auf eine Tabelle in der Datenbank abbzubilden.
Aber Vererbung bedeutet im C++-Sinn eben mehr. So fügt man einen vtable der Klasse hinzu etc.
Jetzt bin ich aber gespannt, wie andere Sprachen virtuelle Methoden auflösen, wenn nicht mit einer Art vtable.
-
boost`rockt schrieb:
rüdiger schrieb:
Wer die Funktion nicht versteht, hätte kein Programmierer werden sollen. Wobei die Überladung wirklich ein wenig sinnlos ist in dem Fall.
Der Operator macht in diesem Fall einfach keinen Sinn, da man & einfach nicht mit serialisieren in Verbindung bringt, wenn man es nicht weiß. Das hat nichts mit Unwissenheit des Programmierers zu tun. Aber ein derartiger "Fehler" ist in diesem Fall natürlich erlaubt, weil es um boost geht ..
Da muss ich dir recht geben. Die Überladung des operator& ist mir unverständlich. Ein << wäre logisch gewesen oder einfach eine funktion serialize.
rüdiger schrieb:
Bietet eben den Vorteil, dass man je nach Datentechnologie eine andere Form der Persistenz wählen kann (z.B: wird man kaum in eine Datenbank serialisieren, sondern eher auf Tabellen abbilden).
Bietet den Vorteil gegenüber welcher Lösung?
Persistenz ist übrigens mehr als Serialisierung
Genau meine Rede, Persistenz ist mehr als Serialisierung, und darum finde ich, dass eine Datenklasse auch nicht selbst entscheiden soll, welche Form der Persistenz verwendet wird (in deinem Fall eben serialisieren). Daher empfehle ich die Persistierung von der Datenklasse zu trennen um entsprechend Wahlmöglichkeiten zu besitzen, um auch z.B: die Daten auf eine Tabelle in der Datenbank abbzubilden.
Wenn ich eine Klasse in eine Datenbank oder eine Textdatei serialisiere, dann ist das immer noch Serialisierung... Und ob ich das in einer Methode der Klasse, zusätzlichen Klasse, globalen Funktion oder wo auch immer mache, das ändert nichts daran und schränkt mich auch nicht in den Möglichkeiten ein, unterschiedlich zu serialisieren.
Was ich meinte, das Persistenz mehr Dinge umfasst als simple Serialisierung, die Serialisierung ist nur ein Schritt und zwar der einfachste. Folgender Artikel gibt dazu einen schönen Überblick (auch wenn er das Design einer Persistenz-Bib für Common Lisp beschreibt) http://weitz.de/eclm2006/rucksack-eclm2006.txt
Aber Vererbung bedeutet im C++-Sinn eben mehr. So fügt man einen vtable der Klasse hinzu etc.
Jetzt bin ich aber gespannt, wie andere Sprachen virtuelle Methoden auflösen, wenn nicht mit einer Art vtable.
hmm, zB über einen Nachrichten Dispatcher :p Nein, ich verstehe schon was du meinst. Aber da wir hier ja eh gerade von den Unterschieden zwischen Java und C++ reden. Java hat im Grunde immer einen vtable. Aber zum einen kann der JIT virtuelle Funktionen eh besser auflösen, als ein normaler Compiler und zum anderen muss man damit einfach leben, wenn man eine Klasse in Java benutzt.
In C++ geht man anders vor, da geht man nicht von oben nach unten ("Ich bepack mich mit so viel Last und schau mal was ich dann noch los werde"), sondern von unten nach oben vor ("Ich schleppe nur das, was dringend erforderlich ist").
-
"Ich bepack mich mit so viel Last und schau mal was ich dann noch los werde"
Naja in Java ist es eben keine Last. Ob ich ein Serializable "implementiere" oder nicht ist eigentlich egal, weil Serializable eh nur eine semantische Sache ist.
Aber ich weis schon was du meinst
