Verkettung abspeichern

mike_abc

Grünschnabel
Hi,
ich hab da ein Problem:
ich habe eine Klasse "Zentrale" und in dieser Klasse eine Verkettung.
Und ich möchte die erzeugte Pointerkette gerne in eine Datei abspeichern und wieder laden könne. Kann mir da vielleicht jemand helfen?

Das ganz sieht in etwa so aus:


class zentrale
{.....
.....
zentrale *next;
.....
};

zentrale *pointer = new zentrale;
 
Das geht leider alles nur indirekt, per Hand.

Mit anderen Worten, zuerst sollte die Anzahl der Glieder der Kette gespeichert werden (ein long sollte auf jeden Fall ausreichend sein). Danach einfach die Member der Klasse (oder falls kein V-Table drin ist, die Klasse direkt als Speicherblock speichern - siehe dazu Anmerkung unten).

Beim Laden zuerst die Anzahl lesen. Dann eine For-Schleife, neue Klasse erzeugen, an vorherige Klasse anhängen.

Anmerkung:
Falls die Klasse als Speicherblock gespeichert worden ist, sind die Pointer im File auch mit drin, diese sind aber als Müll zu betrachten. Die müssen beim Einladen auf jeden Fall neu gesetzt werden. Ich erwähne die Speicherblock-Methode deshalb, weil ein Block üblicherweise schneller geladen werden kann als jedes Member einzeln für sich.
 
Sobald du ein Datenmember hast, das irgendwie einen Pointer drin hat (also auch ein std::string oder CString oder ein std::vector) hast du nach dem Laden einen pervertierten Pointer. Generell ist es sicherer, die Datenmember einzeln zu speichern. Vor allem, wenn man das in Form einer Art Textdatei macht (also nicht in binärer Form), hat man zugleich ein mächtiges Debugging-Werkzeug geschaffen.

@Endurion: Verwirr nicht das Publikum! ;)
Beim Laden zuerst die Anzahl lesen. Dann eine For-Schleife, neue Klasse erzeugen, an vorherige Klasse anhängen.
Besser "Neues Objekt bzw. neue Instanz der Klasse erzeugen, an vorhergehendes Objekt bzw. Listenknoten anhängen." ;)
Es werden ja Objekte einer Klasse gespeichert, nicht Klassen selbst -- die sind ja eher Konzepte.
Ich bitte um Verzeihung für die Besserwisserei!
 
ok. soweit hab ichs verstanden, aber könnte mir jemand sagen,
wie ich das dann konkret in meinem Programm schreiben muss, also den Quellcode (ich mache C++ noch nicht sehr lange :-) )
 
So, ich bin endlich mal dazu gekommen, ein kurzes Beispiel zusammenzustellen. Ich habe eines meiner Projekte genommen und eine passende Stelle soweit zusammengestutzt, dass du damit hoffentlich was anfangen kannst. Ich bin nicht dazugekommen, mieinen zusammenkopierten Code zu testen, aber eigentlich sollte er problemlos laufen und dir als Grundlage für Spielereien dienen können.

Es ist nicht die einfachste Methode, Daten zu speichern, aber es werden einige in Bezug auf C++ wichtige Sachen verwendet:
- Streams im Gegensatz zu den alten fopen()/fclose()- Funktionen
- Operatoren zur Stream-Insertion und -Extraktion
- ein std::vector als Container (für dich käme vermutlich eher eine std::list in Frage)

Tut mir leid, wenn das etwas knifflig wirkt, aber ich denke, es ist besser, dir anhand eines Reallife-Beispiels zu zeigen, wie man das Ganze machen kann, ohne auf die alten C-Monster zurückzugreifen. In dieser Minianwendung lässt sich der Nutzen vielleicht noch nicht erkennen.
Ausserdem wollte ich mir auch nicht mehrere Stunden Zeit für ein halbwegs vollständiges Beispiel nehmen, deshalb das Geschnipsel. ;)

Ich hoffe, es hilft dir weiter. Wenn noch Probleme auftauchen, frag nach.

Code:
#include <iostream>
#include <string>
#include <fstream>

// eine abgespeckte testclass
struct splinepoint
{
  bool smooth, symmetric;
};

// operator zum einfügen eines splinepoints in einen stream ("speichern in text")
inline std::ostream& operator<<(  std::ostream& s, splinepoint& p )
{
  s << p.smooth   << " " << p.symmetric;
  return s;
}

// operator zum extrahieren eines splinepoints aus einen stream ("lesen aus text")
inline std::istream& operator>>(  std::istream& s, splinepoint& p )
{
  s >> p.smooth   >>  p.symmetric;
  return s;
}



// ein fast überflüssiges typedef
typedef std::vector<splinepoint>   vectSplinePoints; 

// ein std::vector von splinepoints
vectSplinePoints       m_SplinePoints;

// funktion zum speichern der splinepoints in textdatei
void SaveSpline( std::ostream& s )
{
  vectSplinePoints::iterator it( m_SplinePoints.begin() ), itend( m_SplinePoints.end() );
  for ( ; it != itend; ++it )
  {
    s << "point " << *it << "\n";
  }
}

// funktion zum laden der splinepoints aus textdatei
void LoadSpline( std::istream& s )
{
  char szTemp[5000];
  std::string temp;
  m_SplinePoints.clear();
  while ( s )
  {
    s >> szTemp;
    temp = szTemp;
    // s >> temp;
    if ( temp == "point" )
    {
      splinepoint p;
      s >> p;
      m_SplinePoints.push_back( p );
    }
  }
}


int main()
{
  // alles nur dummy, bitte ausprobieren

  // laden  
  std::ifstream s( "einedatei.txt" );
  LoadSpline( s );

  //speichern
  std::ofstream s( "einedatei.txt" );
  SaveSpline( s );

  return 0;
}
 
danke für die Hilfe!

Also wenn ich es jetzt noch nicht hinbekomme, dann bin ich zu doof zum programmieren ;)

Aber das sollte jetzt schon funktionieren
 
Zurück