Ein- und Ausleseverfahren von eigenen Datentypen konstistent halten
-
Hi,
aus dem anderen Thread meine ich zu wissen, wo er sein Problem hat: Man kann z.B. bei längeren Attributlisten beim Einlesen versehentlich eine andere Reihenfolge bekommen als beim Schreiben (oder bei einer der beiden ein neues Attribut vergessen).
Gruß,
Simon2.
-
Simon2 schrieb:
gute Frage - habe ich auch schon vermisst, aber ich vermute, dass das nicht geht ... oder eben nur mit so viel "Metadaten", dass das sehr kompliziert und letztlich unkomfortabel und nicht wirklich weniger fehleranfällig ist.
Alternativ könnte man natürlich alle seine Attribute in einen entsprechenden Container verpacken und den dann sequentiell ein- und auslesen - aber auch das macht den Zugriff auf die Attribute kompliziert und um einen generischen und trotzdem typsicheren Container muss man sich auch erstmal bemühen...
(könnte man mit gemeinsamer Basisklasse für alle seine Atributtypen lösen)Hmmm, alles gute Ideen und je mehr ich darüber nachdenke um ne Lösung zu finden, fällt mir nichts besseres dazu ein, als das was du geschrieben hast.
thordk schrieb:
versteh dein problem nicht. du willst mit daten eines streams dein objekt füllen?
Simon hats verstanden

thordk schrieb:
und...
istream& operator>>(istream& stream, Loo& obj) { stream >> // in obj return stream; }wieso gibt der op nen stream zurück? wenn ich in dein objekt daten schubse, erwarte ich, dass nen objekt zurückgeliefert wird, in dass ich weitere daten schubsen kann. und nicht nen stream der... was genau macht?
Das ist schon richtig so, will schließlich den stream zurückbekommen und weiterhin damit arbeiten zu können:
istream file("..."); Loo a,b,c; file >> a >> b >> c;thordk schrieb:
wenn ich in dein objekt daten schubse, erwarte ich, dass nen objekt zurückgeliefert wird, in dass ich weitere daten schubsen kann.
file >> a;Wäre ja wohl seltsam, wenn das Ergebnis des Audrucks, das a-Objekt wäre.
Denke mal du hast dich gerade irgendwie *verdenkt*

-
KasF schrieb:
...
thordk schrieb:
versteh dein problem nicht. du willst mit daten eines streams dein objekt füllen?
Simon hats verstanden

...Naja, kein Kunststück, wenn man die Frage bereits aus einem anderen Zusammenhang kennt ;)....
Gruß,
Simon2.
-
*Aufgeflogen*

Back to Topic ...
-
hoi
du koenntest dir die beiden operatoren '<<, >>' als template schreiben und jeder klasse die streamfaehig sein soll z.b. eine Serialize und eine Deserialize methode verpassen. dann kuemmern sich die klassen selbst um die reihenfolge der daten.class my_stream_class { private: int value1, value2; public: void Serialize(std::ostream &out) const { // hier in den stream schreiben. reihenfolge beachten } void Deserialize(std::istream &in) { // hier auslesen. auf die reihenfolge achten } }; template<class T> std::ostream& operator<<(std::ostream &out, const T &value) { value.Serialize(out); return out; } template<class T> std::istream& operator>>(std::istream &in, T &value) { value.Deserialize(in); return in; }wenn ich es richtig im kopf habe muesste der kompiler gucken ob es eine bessere bzw. ueberladene funktion fuer 'T' gibt und diese auswaehlen. falls nix gefunden wird probiert er es mit dem template und versucht die methoden Serialize und Deserialize aufzurufen. dadurch sollte es mit build-ins usw. keine probleme geben. berichtigt mich mal wenn das falsch ist. hab mir das mal grad so zusammen gedacht.
vielleicht auch noch einen konstruktor mit nem istream als parameter einrichten, dann kann das objekt seine initialisierungsdaten gleich aus dem stream rauslesen.Meep Meep
-
Hi Meep,
ich glaube, Du hast hier einen Vorschlag gemacht, der zwar nicht falsch ist, aber KasFs eigentliches Problem nicht löst

Meep Meep schrieb:
... void Serialize(std::ostream &out) const { // hier in den stream schreiben. reihenfolge beachten } void Deserialize(std::istream &in) { // hier auslesen. auf die reihenfolge achten } ...Genau DAS will KasF ja automatisieren: Die Vollständigkeit, richtige Reihenfolge und identisches Speicherformat aller Attribute.
Ehrlich gesagt sehe ich in dem Einführen dieser Methoden keinen wirklichen Vorteil (außer, dass Javaprogrammierer es vllt. etwas schneller kapieren
)...Gruß,
Simon2.
-
re
naja vollautomatisieren wird wohl schwer sein.
koennte man sich auch einen codegenerator schreiben, dem man einfach die variablen , klassennamen usw. uebergibt und er erstellt mal das grundgeruest mit den stream-funktionen.andere idee die vielleicht mal nen anfang machen koennte waere folgend:
class istream_operator { typedef std::istream stream_type; stream_type &stream_t; public: istream_operator(stream_type &stream) : stream_t(stream) { } template<class T> istream_operator& operator()(T &value) { stream_t >> value; return *this; } }; class ostream_operator { typedef std::ostream stream_type; stream_type &stream_t; public: ostream_operator(stream_type &stream) : stream_t(stream) { } template<class T> ostream_operator& operator()(const T &value) { stream_t << value << " "; return *this; } };dann muss man in seiner klasse nur noch folgende template-funktion implementieren:
struct my_class { int integer; float real; char c; bool b; template<class T> virtual void Streaming(T &stream_type) // <- diese dada { //hier gibt man dann die attribute der reihe nach ein. //im schoenen klammernstyle stream_type(integer)(real)(c)(b); } };und fuer die globalen stream-operatoren noch:
inline std::ostream& operator<<(std::ostream &out, const my_class &my) { static_cast<my_class>(my).Streaming(ostream_operator(out)); return out; } inline std::istream& operator>>(std::istream &in, my_class &my) { my.Streaming(istream_operator(in)); return in; }der static_cast gefaellt mir da zwar ueberhaupt nicht, aber da is mir grad nix besseres eingefallen.
is das jetz sowas in der art wie KasF gesucht hat oder bin ich scho wieder meilenweit weg ?
Meep Meep
-
@Meep Meep: Das gefällt mir schonmal sehr gut

Nur würde ich Streaming() const machen und an Streaming keine tempöreren Objekte übergeben, finde es schon komisch, dass du temporäre Objekte an nicht const Referenzen binden kannst ...
Das static_cast würde auch wegfallen. ( obwohl da doch ein const_cast hinmusste was Ref's castet ??? )
Trotzdem der entscheidende Punkt hier:
stream_type(integer)(real)(c)(b);Was eigentlich keine Fehler zulässt und die op()'s auch einfach gehalten sind ...
-
KasF schrieb:
Nur würde ich Streaming() const machen
wie willst du das machen ? dann bekommst beim einlesen leichte probleme. oder versteh ich dich da jetzt falsch ?
Meep Meep
-
Ja stimmt, hast Recht.
Habe mich irgendwie *verdenkt*