Einzelnen Beitrag anzeigen

KrasserChecker

Registriert seit: 21. Jul 2004
120 Beiträge
 
#2

Re: Vererbung - Abspeichen in Streams

  Alt 11. Sep 2006, 11:23
Eine Grundregel von OOP ist ja: Objekte sollten für sich selbst verantwortlich sein.
Daher solltest du in der Basisklasse "TElement" schon mal die beiden Methoden "SaveToStream" & "LoadFromStream" vorsehen (und auch gleich virtuell machen).

Danach schreibst Du deine Liste so um, dass zuerst der Klassename mit weggeschrieben wird. Darüber kannst du beim Laden dann wieder das richtige Objekt erzeugen.

Delphi-Quellcode:
TElement = class
  show: boolean;
  (...)
public
  procedure SaveToStream(Stream: TStream); virtual;
  procedure LoadFromStream(Stream: TStream); virtual;
end;
  
TExElement1 = class(TEElement)
  elemID: integer;
  (...)
public
  procedure SaveToStream(Stream: TStream); override;
  procedure LoadFromStream(Stream: TStream); override;
end;


...

procedure TElement.SaveToStream(Stream: TStream);
begin
  Stream.Write(show, sizeof(show));
end;

procedure TElement.LoadFromStream(Stream: TStream);
begin
  Stream.Read(show, sizeof(show));
end;


procedure TExElement1.SaveToStream(Stream: TStream);
begin
  inherited;
  Stream.Write(elemID, sizeof(elemID));
end;

procedure TExElement1.LoadFromStream(Stream: TStream);
begin
  inherited;
  Stream.Read(elemID, sizeof(elemID));
end;

procedure TElementList.SaveToStream(Stream: TStream);
var i,len: integer;
begin
  len := Count;
  Stream.Write(len, SizeOf(len));
  for i := 0 to Count - 1 do
  begin
    // Länge des Klassennamens & Klassennamen als String wegschreiben, damit
    // wir später wieder ermitteln können, was für eine Klasse dahinter steckt.
    len := Length(Items[i].Classname);
    Stream.Write(len, SizeOf(len));
    Stream.Write(Items[i].Classname, Length(Items[i].Classname));
   
    // Jetzt lassen wir das Objekt sich selbst in den Stream schreiben
    Items[i].SaveToStream(Stream);
  end;
end;

procedure TElementList.LoadFromStream(Stream: TStream);
var NewElement: TElement; i,Len, ObjCount: integer; cn: string;
begin
  Stream.Read(ObjCount, SizeOf(ObjCount));
  for I := 0 to ObjCount - 1 do
  begin
    // Erstmal Klassennamen wieder auslesen und Objekt erzeugen
    Stream.Read(Len, SizeOf(Len));
    SetLength(cn, Len);
    Stream.Read(cn[1], Len);
    
    if cn = 'TElementthen
      NewElement := TElement.Create
    if cn = 'TExElement1then
      NewElement := TExElement1.Create
    if cn = 'TExElement2then
      NewElement := TExElement2.Create
    else
      raise Exception.Create('unbekannte Klasse: '+cn);

    // Jetzt lassen wir das Objekt wieder seine Daten auslesen
    NewElement.LoadFromStream(Stream);

    // Objekt mit in die Liste ausnehmen
    Add(NewElement);
  end;
end;
  Mit Zitat antworten Zitat