Klasse mit STL-List in Datei schreiben
-
Klar, wie soll das denn gehen?
Die Liste besitzt intern einen Zeiger auf das erste und einen auf das letzte Element. diese Zeiger speicherst du, ohne auch nur irgendeins der in der Liste enthaltenen Objekte. Beim Laden erzeugst du dann eine liste die glaubt auf ein erstes und ein letztes Element zu verweisen, in wirklichkeit verweisen die dinger aber irgendwo hin, wo sie besser nicht hinzeigen sollten.
-
Helium schrieb:
Die Liste besitzt intern einen Zeiger auf das erste und einen auf das letzte Element. diese Zeiger speicherst du, ohne auch nur irgendeins der in der Liste enthaltenen Objekte. Beim Laden erzeugst du dann eine liste die glaubt auf ein erstes und ein letztes Element zu verweisen, in wirklichkeit verweisen die dinger aber irgendwo hin, wo sie besser nicht hinzeigen sollten.
das ist klar. deswegen will ich ja zuerst die liste leeren und danach die listenelemente wieder mit push_back() einfügen. deswegen speicher ich sie extra neben der klasse ab.
aber so weit komm ich komischerweise erst gar nicht...
-
Snatcher schrieb:
das ist klar. deswegen will ich ja zuerst die liste leeren und danach die listenelemente wieder mit push_back() einfügen. deswegen speicher ich sie extra neben der klasse ab.
aber so weit komm ich komischerweise erst gar nicht...
und während ich den beitrag abschicke, fällt mir die antwort glaube ich selber ein. auch ein list.clear() versucht natürlich auf die elemente der list zuzugreifen und den destruktor aufzurufen etc. Deswegen gehts in die hose vermut ich?!?
hat da jemand ne idee, wie man das problem trotzdem lösen kann?
-
Du erstellst eine Liste alle:
std::list<T> myList;
liest die Elemente aus der Datei und schiebst sie einzeln in die Liste.
Man könnte auch den op<< und op>> für die std::list<DeinTyp> überladen.
Schau mal in die FAQ: Speichern und Laden eines Vectors o.ä. Das geht im prinzip mit der Liste genauso.
-
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.