Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Probleme im Klassendesign-Objektliste und Typ der Einträge (https://www.delphipraxis.net/64588-probleme-im-klassendesign-objektliste-und-typ-der-eintraege.html)

Keldorn 5. Mär 2006 17:38


Probleme im Klassendesign-Objektliste und Typ der Einträge
 
Hallo

Ich habe in meinem code viele Objekte und Objektlisten, die sich selbst in einen stream speichern und laden können und wie folgt aufgebaut sind

Delphi-Quellcode:
//Liste
procedure TObjektListe.LoadFromStream(Stream: TStream);
Var Version:integer;
    i,len:integer;
    Eintrag: TListeneintrag;
  begin
    clear;
    with TReader.create(Stream,FileStreamBuffer) do
    try
      //Version auslesen
      Version:=ReadInteger;
      len:=readinteger;
      … weitere Eigenschaften aus stream laden
    finally
      free;
    end;
    //einträge auslesen
    for i:=0 to len-1 do
      begin
        Eintrag:= TListeneintrag.Create;
        Eintrag.LoadFromStream(stream);
        add(Eintrag);
      end;
  end;
//Eintrag:
procedure TListeneintrag.LoadFromStream(Stream: TStream);
var Version:integer;
  begin
    with TReader.create(Stream,FileStreamBuffer) do
    try
      //Version auslesen
      Version:=ReadInteger;

      Eigenschaft1 := ReadString;
      Eigenschaft2 := ReadString;
      …
      If Version>Version43 then
        EigenschaftXYZ := ReadString;
    finally
      free;
    end;
  end;
Savetostream der beiden entsprechend. Die Version dient mir zum flexiblen Erweitern der Datei um neue Eigenschaften.
Ich möchte gern diesen code, dessen Rumpfbereich in allen Objekten und ObjektListen vorkommt gern verallgemeinern, da der code sich ständig wiederholt und ich teilweise einen Haufen Warnungen wegen der Nichtbenutzung der Version erhalte (nicht jedes Objekt ändert sich ständig im Dateiaufbau).
Ich hätte gern ein Basisobjekt, das wie folgt aussieht:
Delphi-Quellcode:
TBasisListenEintrag=class…
  Private
     Procedure LoadfromStream…
     Procedure Savetostream…
  Public
     Procedure SaveData… //soll die abgeleitete Klasse
     Procedure Loaddata… //erst implementieren
….
procedure TBasisListenEintrag.LoadFromStream(Stream: TStream);
var DateiVersion:integer;
  begin
    with TReader.create(Stream,FileStreamBuffer) do
    try
      //Version auslesen
      Dateiversion:=ReadInteger;

      LoadData(Reader,Dateiversion)
    finally
      free;
    end;
  end;

//abgeleitetes Objekt:
procedure TAbgeleiteterListenEintrag.LoadData(Reader:Treader;const Dateiversion:integer);
  begin
    with reader do
      begin  
        Eigenschaft1 := ReadString;
        Eigenschaft2 := ReadString;
        …
        If DateiVersion>Version43 then
          EigenschaftXYZ := ReadString;
      end;
  end;
Das abgeleitete Objekt soll nur die Daten lesen und schreiben, der Reader/Writer soll im Basisobjekt bei load/savetostream erstellt werden, das abgeleitete Objekt soll davon nichts mitbekommen.

Für das Objekt ist das auch kein Problem, scheitern tue ich an der Objektliste
Delphi-Quellcode:
procedure TBasisObjektList.LoadFromStream(Stream: TStream);
Var Version:integer;
    i,len:integer;
    Eintrag: T????;
  begin
    clear;
    with TReader.create(Stream,FileStreamBuffer) do
    try
      //Version auslesen
      Version:=ReadInteger;
      len:=readinteger;
      //weitere Eigenschaften aus stream laden
      Loaddata(…)
    finally
      free;
    end;
    //einträge auslesen
    for i:=0 to len-1 do
      begin
        Eintrag:= T????.Create;
        Eintrag.LoadFromStream(stream);
        add(Eintrag);
      end;
  end;
Bei Eintrag:= T????.Create; müsste ich wissen, welche abgeleitete Klasse die Objektliste verwaltet. Wenn ich Eintrag als TBasisobjekt angebe, rufe zwar loadfromstream auf, aber an das eigentliche auslesen der Daten per loaddata komm ich nicht ran.

Geht das überhaupt? Kann ich die Objektliste z.B. so flexibel gestalten das man z.B. beim create der objektliste den Typ der Einträge mit übergeben kann, oder gibt es eine andere Lösungsmöglichkeit?

Danke im Voraus Frank

marabu 5. Mär 2006 17:46

Re: Probleme im Klassendesign-Objektliste und Typ der Einträ
 
Hallo Frank,

rein theoretisch müsstest du nur LoadData() in der Basisklasse als virtual deklarieren und in der abgeleiteten Klasse mit der override Direktive überschreiben. Machst du das schon so?

Grüße vom marabu

Keldorn 5. Mär 2006 17:56

Re: Probleme im Klassendesign-Objektliste und Typ der Einträ
 
Hallo Marabu,

ich hatte (als einen von vielen Versuche ;) ) loaddata in der Basisklasse als virtuel abstract.
wenn ich in der basisobjektliste dann
Delphi-Quellcode:
    //einträge auslesen
    for i:=0 to len-1 do
      begin
        Eintrag:= TBasisobjekt.Create;
        Eintrag.LoadFromStream(stream);
        add(Eintrag);
      end;
stehen habe, lande ich in abstrakten Fehler. Ich rufe zwar loadfromstream des Basisobjektes auf, aber das weiß mit loaddata dann auch nicht wohin, da dies erst im abgeleiteten Objekt implementiert wird. ich müßte Eintrag:= TAbgeleitetesobjekt.Create; stehen haben, aber welches AbgeleiteteObjekt die Liste verwaltet, weiß die Basisliste nicht.

Der_Unwissende 5. Mär 2006 18:02

Re: Probleme im Klassendesign-Objektliste und Typ der Einträ
 
Hi,
der wahrscheinlich üblichste, schönste, was weiß ich Weg ist es wohl Templates zu benutzen oder Generics (weiß gerade nicht wie die in Delphi heißen).
Ein vielleicht nicht so schöner aber allemal einfacher Weg ist es, wenn du mit einer Variablen als Metaklasse arbeitest.
Dazu brauchst du nur so etwas wie
Delphi-Quellcode:
type
  TMetaClass = class of TObject;

...
var x : TMetaClass;
begin
  x := TStringList; // oder halt eine beliebige Klasse, die Nachfahre von TObject ist
  result := x.Create;
end;
Ein Problem dass du hierbei bekommen könntest ist natürlich, dass du nicht immer den Standardkonstruktor zur Verfügung hast und du eventuell nicht weißt, was für Parameter du bekommst.

Hoffe es hilft dir trotzdem weiter

Gruß Der Unwissende

Keldorn 5. Mär 2006 18:14

Re: Probleme im Klassendesign-Objektliste und Typ der Einträ
 
:-D, Danke. Das sieht erstmal gut aus, damit muß ich mich näher beschäftigen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz