Klasse mit STL-List in Datei schreiben
-
aber ich brauche die listenelemente sortiert in den klasseninstanzen. in einer extra liste sind sie in meinem fall relativ wertlos.
-
Wo ist das Problem ?!
Du hast eine Liste:
std::list<T> temp;
Diese schreibst Du in eine Datei. A B C D E F G etc...
Irgendwann erstellst Du wieder eine Liste:
std::list<T> loadList;
Und liest nun:
A -> ab in die Liste
B -> ab in die Liste
.
.
.
G -> ab in die ListeWo ist da nun das Problem ?
Du kannst AFAIK nicht einfach ein Speicherabbild der Liste in eine Datei schreiben. Oder hab ich das Problem nun total verpeilt ?!
-
Soweit ist das klar. Das Problem ist aber, dass die Liste eine Variable der Klasse ist. Wenn ich die Klasse aus der Datei auslese habe ich dann in der Klasse eine Liste mit ungültigen Zeigern.
D.h. ich kann kein list.clear() machen um die Elemente dann wieder einzufügen.
Ich hoffe mein Problem ist jetzt etwas klarer geworden
-
Nö.
Wie schreibst Du denn die eigene Klasse weg ?
-
na
file.write(reinterpret_cast<char*>(&class),sizeof(class));
-
Nu schau Dir den Beitrag für Helium an.
Das gilt auch für Deine Klasse die Du so schreibst.Du musst jeden Member schon selbst in die Datei schreiben.
-
du kannst nicht die komplette klasse in die liste schreiben.
erst alles von der klasse AUSSER der liste in die datei,dann nacheinander alle listenelemente rein(also wieder nicht die liste).
ausgelesen wird dann zeurst die klasse,ohne die liste,und dann ganz einfach mit pushback und einlesen.
-
Das mach ich doch:
vor dem speichern lösche ich die liste, die ich vorher zwischengespeichert habe:
iter->chips.clear();
Dann speicher ich das Objekt in die Datei:
file.write(reinterpret_cast<char*>(&(*iter)), sizeof(Class));
Und dann die Anzahl der listenelemente und die elemente selbst:
file.write(reinterpret_cast<char*>(&Anzahl), sizeof(int)); for(blablubb) file.write(reinterpret_cast<char*>(&(*citer)), sizeof(Class2));
Nach dem Einlesen hätte ich gedacht, dass ich dann normal auf die Liste zugreifen und die Elemente einzeln wieder einfügen kann, da die Liste ja leer war, als sie abgespeichert wurde. Dem ist aber leider nicht so. Jeder Versuch eines Zugriffs bringt mir eine Zugriffsverletzung
-
Wirf mal nen Blick in die FAQ vectoren speichern und laden.
Irgendwie reden wir hier gegen eine Mauer.
Was glaubst Du denn was Du da abspeicherst in die Datei ?
Ein Speicherabbild. Das hat aber mit deinem Objekt wenig zu tun!
Du musst für denen Member extra einen Aufruf fürs speichern generieren.
Wenn der member wieder eine Klasse ist geht das da wieder los. Für jeden Member (Dateninhalt) extra einen Aufruf fürs speichern.Du kannst nur Deine Daten die Du mit hilfe der Objekte verwaltest speichern, nicht aber das Objekt selbst.
In einem Buch steht auch nur die Geschichte, den Auhor haste aber nicht.
-
Knuddlbaer schrieb:
Du kannst nur Deine Daten die Du mit hilfe der Objekte verwaltest speichern, nicht aber das Objekt selbst.
Bei anderen Klassen, die keine liste o.ä. enthalten funktioniert es aber tadellos.
z.B.
Speichern:
file.write(reinterpret_cast<char*>(&mychip), sizeof(CChip));Lesen:
CChip tmpchip;
infile.read(reinterpret_cast<char*>(&tmpchip), sizeof(CChip));Aber wahrscheinlich ist das Problem zu kompliziert oder ich zu unfähig, um es hier gescheid zu formulieren :p
Trotzdem danke für die Mühen
-
Hm, vllt bin ich auch nur zum Umständlich beim erklären.
Schau Dir mal das Überladen von Operatoren an.
Überlade den operator << und >> für Deine Klasse. Da haste dann viel mehr
einfluss auf das was passiert und Du hast diese Probleme nicht.
-
Knuddlbaer schrieb:
Hm, vllt bin ich auch nur zum Umständlich beim erklären.
Schau Dir mal das Überladen von Operatoren an.
Überlade den operator << und >> für Deine Klasse. Da haste dann viel mehr
einfluss auf das was passiert und Du hast diese Probleme nicht.Wieso sollte ich diese Probleme nicht haben? Es geht mir nicht nur darum, die Klassen zu vervielfältigen, sondern sie sollen wirklich permanent gespeichert und zu anderem zeitpunkt wieder gelesen werden.
-
Bei anderen Klassen, die keine liste o.ä. enthalten funktioniert es aber tadellos.
Ja, aber diese Klasse enthält eine Liste. Soltlest du es mit Klassen versuchen, die virtuelle Methoden enthalten wirst du noch größere probleme bekommen.
Solche Aussagen sind dämlich!
char x = 1232134.123;
Verdammt das geht nicht. Warum nicht? Bei anderen Typen (z.B. float, double, ...) geht das doch auch.
-
Ich finde, dass du ziemlich unfair wirst.
hatte das nur gesagt, um die verallgemeinerung von Knuddlbaer :
Du kannst nur Deine Daten die Du mit hilfe der Objekte verwaltest speichern, nicht aber das Objekt selbst.
zu widerlegen, und nicht um irgendwas daherzulabern...
aber ist egal, will mich auch nich streiten, außerdem ist das problem eh schon gelöst, umständlicher zwar, aber gelöst.
trotzdem danke
-
Snatcher schrieb:
Knuddlbaer schrieb:
Hm, vllt bin ich auch nur zum Umständlich beim erklären.
Schau Dir mal das Überladen von Operatoren an.
Überlade den operator << und >> für Deine Klasse. Da haste dann viel mehr
einfluss auf das was passiert und Du hast diese Probleme nicht.Wieso sollte ich diese Probleme nicht haben? Es geht mir nicht nur darum, die Klassen zu vervielfältigen, sondern sie sollen wirklich permanent gespeichert und zu anderem zeitpunkt wieder gelesen werden.
aua
void operator <<(ofstream& of,deine_Klasse& inhalt){ of<<inhalt.getzahl();//wirst ja die werte nich public haben^^ for(list<typ_deiner_Liste>::const_iterator position=inhalt.getliste().begin();pos<inhalt.getliste().end();++position){ of<<*position; } } //in der main ofstream datei("datei.txt,ios::binary): datei<<deine_Klasse; //ende
-
@otze: Nach dem Motto: Warum einfach, wenn's auch kompiliert geht?
Und nebenbei noch "falsch".Warum empfängst du einen ofstream? ein ostream wäre doch viel allgemeiner und sinnvoller? Warum gibtst du void zurück, statt den stream durchzureichen, warum gibst du die Klasse nicht als konstante Referenz, ... ?
Und was macht die äußere schleife da? soll die Liste mehrfach gespeichert werden?
Um deine Bezeichnungen weiter zu verwenden:
ostream & operator << (ostream & of, deine_Klasse const & inhalt) { of<<inhalt.zahl; copy (inhalt.name_deiner_liste.begin(), inhalt.name_deiner_liste.end(), ostream_iterator<typ_deiner_Liste>(of, "delimiter")); return of; } //in der main ofstream datei("datei.txt",ios::binary): datei<<deine_Klasse; //ende
Erst min einem Kommentar wie "aua" beleidigen und dann so einen Müll verzapfen.
-
Danke, jetzt hab ichs kapiert
-
Ich finde, dass du ziemlich unfair wirst.
Ich habe auf meine zugegebener Maßen sarkastische weiße versucht klarzumachen, dass deine Aussage keinerlei Inhalt besaß.
-
jaja wenn du richtig gelesen hättest, hättest du gemerkt dass ich einen iterator benutzt habe, und für den brauch man ne schleife...aber wieso lesen?
ich return den of/ostream nicht, weil es für mich noch nie eine situation gegeben hat, wo ich das gebraucht hätte. Es funktioniert, und das is meienr meinung nach das wichtigste.
auch wenn ich das const prinzip kenne,habe ich mich bisher nie dafür intressiert, weil mir der sinn relativ schleierhaft ist.
//edit achso die for schleife meinst du, ok da stand vorher was andres, hab ich wohl versehentlich beim überkopieren net markiert gehabt-.-
-
jaja wenn du richtig gelesen hättest, hättest du gemerkt dass ich einen iterator benutzt habe, und für den brauch man ne schleife...aber wieso lesen?
Dito. Ich verwende gleich zwei bidirektionale Iteratoren und einen Forwarditerator. Alle jedoch unbenannte Objekte, tut mir leid. Beim nächsten mal schreibe ich:
list<typ_deiner_Liste>::const_iterator begin = inhalt.name_deiner_liste.begin(); list<typ_deiner_Liste>::const_iterator end = inhalt.name_deiner_liste.end(); ostream_iterator<typ_deiner_Liste> out(of, "delimiter"); copy (begin, end, out);
Nur für dich.
ich return den of/ostream nicht, weil es für mich noch nie eine situation gegeben hat, wo ich das gebraucht hätte.
Du hattest noch nie sowas, wie
cout << "foo: " << foo << '\n';
Hier wird dieses Prinzip gleich mehrfach angewendet.
Es funktioniert, und das is meienr meinung nach das wichtigste.
Anfängerausreden, mit denen du nicht weit kommst. :p