|
Antwort |
Registriert seit: 5. Aug 2003 Ort: Osnabrück 505 Beiträge Delphi 2005 Professional |
#1
Eine Objectliste kann man nich so leicht Speichern. Jedoch sollte dieser Ansatz euch eine doch recht einfache Lösung zeigen.
Beschreibung: Unit: Daten Zweck: Erstellen einer speicherbaren Objectliste mit polymorphen Objecten Beschreibung: TMyObjectList Von einer TObjectlist wird eine neue Klasse Namens TMyObjectList abgeleitet. Diese erhält weitere Routinen. Diese lauten SafeToStream, LoadToStream, SaveToFile und LoadToFile. Die function Add und die Eigenschaft Items werden Überschreiben, da die Objectliste sich nicht auf eine Klasse speicherbarer Objecte fest legen soll. Ebenfalls wird der Constructor überschrieben. Die Eigenschaft Items ist eine ReadOnly-Eigenschaft. Da es sich bei Items um ein Array handelt, muß eine Funktion die Rückgabe des Wertes übernehmen. Die polimorphen Objecte werden während der Laufzeit zum Auslesen noche einmal Registriert durch die procedure RegisterObeject (In diesen Beispiel nur eines). TBaseObject: Eine Ableitung von TPersistent. Nur so kann das Object nach den Auslesen neu bestimmt (RegisterClass) und gesucht (FindClass) werden. Dieses Object hat die proceduren LoadFromStream und SaveToStream virtual (damit die untergeordneten Klassen sie Überschreiben können) und abstract (so brauch diese Methode erst in der abgeleiteten Klasse definiert werden). TObjectClassRef: Vordefinierung für eine Classenrefernz. Durch das Wörtchen "of" ermöglicht dieser Typ die polimorphen Objecte. TName: Ableitung des TBaseObjectes. Hier werden alle gewünschten Eigenschaften, Methoden usw. eingetragen. Durch die Methoden SafeToStream und LoadFromStream erhält das Object die gewünschte Speicher-/Ladefunktion. Diese Methoden müssen jedoch für jede Ableitung des TBaseObjectes speziell definiert werden. Nutzung: Hinzufügen von Daten erfolgt wie üblich bei einer ObjectList. Bespiel: Name := TName.Create; Name.ID := 0; Name.Name := 'Egon'; Name.Herkunft := 'Deutschland'; Name.Geschlecht := true; ObjectListe.Add(Name); Auslesen ist schon schwiriger. Hier muß immer der Typ der Basisklasse der Procedur bekannt sein. Bespiel: Name := ObjectListe.Items[index] as tname; showmessage(Name.name); Speichern in Dateien ist auch nicht schwer: Beispiel: ObjectListe.SaveToFile('Test.dat'); Dazu das Laden: Beispiel: ObjectListe.LoadFromFile('Test.dat'); ObjectListe in einen Stream speichern: Beispiel: ObjectListe.SaveToStream(aStream); ObjectListe aus einen Stream lesen: Beispiel: ObjectListe.LoadFromStream(aStream);
Delphi-Quellcode:
[edit=Chakotay1308]SourceCode korrigiert und Hinweise eingefügt. Mfg, Chakotay1308[/edit]
unit daten;
interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, Contnrs; // Basisklassen type TBaseObject = class (TPersistent) protected procedure LoadFromStream(Reader:TReader); virtual; abstract; procedure SaveToStream(Writer:TWriter); virtual; abstract; end; //Referenztyp zur Klassifiezirung der Daten type TObjectClassRef = Class of TBaseObject; //Hier werden die unterschiedlichen Typen des BaseObjects deklariert //Die Namen der TBaseObject-Ableitungen MÜSSEN einzigartig sein! TName = class(TBaseObject) private fID : Integer; fName : String; FHerkunft : String; fGeschlecht : Boolean; protected procedure LoadFromStream(Reader:TReader); override; procedure SaveToStream(Writer:TWriter); override; public property ID : Integer Read fID Write fID; property Name : String Read fName Write fName; property Herkunft : String Read fHerkunft Write fHerkunft; property Geschlecht : Boolean Read fGeschlecht Write fGeschlecht; end; //Und natürlich das wichtigste. Die Objectliste, mit der gearbeitet wird. //Hiervon können natürlich weitere Objecte abgeleitet werden. type TMyObjectList = class(TObjectList) private protected function GetItem(Index:Integer):TBaseObject; procedure RegisterObjects; public constructor Create; function Add(AObject:TBaseObject):Integer; procedure LoadFromStream(Stream:TStream); procedure SaveToStream(Stream:TStream); procedure LoadFromFile(FileName:String); procedure SaveToFile(FileName:String); property Items[Index:Integer]:TBaseObject read GetItem; end; implementation procedure TName.LoadFromStream(Reader:TReader); begin //Hier werden die Daten aus den Reader gelesen fID := Reader.ReadInteger; fName := Reader.ReadString; fHerkunft := Reader.ReadString; fGeschlecht := Reader.ReadBoolean; end; procedure TName.SaveToStream(Writer:TWriter); begin //Hier werden die Daten in den Writer geschrieben Writer.WriteInteger(fID); Writer.WriteString(fName); Writer.WriteString(fHerkunft); Writer.WriteBoolean(fGeschlecht); end; { Nicht zugeordnete Methoden } procedure WriteClassRef(Writer: TWriter; o: TObject); begin // Bestimmen und Schreiben des Klassennamens Writer.WriteString(o.ClassName); end; function ReadClassRef(R: TReader): TClass; var ClassName: String; begin //Auslesen des KlassenNamens ClassName := R.ReadString; //Rückgabe des Klassennamens Result := FindClass(ClassName); end; { Methoden der Basisklasse Objectliste } constructor TMyObjectList.Create; begin //Aufrufen der ererbten Methode Create inherited Create(true); end; procedure TMyObjectList.RegisterObjects; begin //Registrierung der TBaseObject-Ableitungen RegisterClass(TName); end; function TMyObjectList.Add(AObject:TBaseObject):Integer; begin //Hinzufügen eines TBaseObjectes zur Objectliste result:=inherited Add(AObject); end; function TMyObjectList.GetItem(Index:Integer):TBaseObject; begin //Rückgabe eines TBaseObjectes durch die ererbte Methode Items[index] result:=TBaseObject(inherited Items[Index]); end; procedure TMyObjectList.LoadFromStream(Stream:TStream); var i : Integer; NewObjectRef : TObjectClassRef; Reader : TReader; NewObject : TBaseObject; begin //Aufruf der nachträglichen Registrierung der TBaseObject RegisterObjects; //Erstellen eines Readers Reader := TReader.Create(Stream, 1024); //Löschen des aktuellen Inhalts der aktuellen ObjectList Clear; //Auslesen der Menge der abgespeicherten Objecte count := Reader.ReadInteger; for i:=0 to count-1 do begin //Auslesen des Typs der TBaseObject-Ableitung NewObjectRef := TObjectClassRef(ReadClassRef(Reader)); //Erstellen eines neuen Instanz dieser Ableitung NewObject := NewObjectRef.Create; //Auslesen der gespeicherten Informationen NewObject.LoadFromStream(Reader); //Einfügen an ausgeleser Position in der Objectliste Insert (i, NewObject); end; //Freigabe des Readers Reader.Free; end; procedure TMyObjectList.SaveToStream(Stream:TStream); var i,c : Integer; Writer : TWriter; begin // Erstellen eines TWriters writer := TWriter.Create(Stream, 1024); // Abfrage, wie viele Objecte die Objectliste enthält c:=Count; // Schreiben der Objectanzahl Writer.WriteInteger(C); for i:=0 to c-1 do begin // Schreiben des TBaseObjects-Typen-Namen WriteClassRef(Writer, Items[i]); // Speichern der gewünschten Informationen Items[i].SaveToStream(Writer); end; // Freigabe des Writers Writer.Free; end; procedure TMyObjectList.LoadFromFile(FileName:String); var Stream : TFileStream; begin // Öffnen der Datei Stream := TFileStream.Create(FileName, fmOpenRead); // Aufruf von LoadfromStream, da alle notwendigen Funktionen hier schon // definiert wurden LoadFromStream(Stream); // Freigabe des Streams Stream.Free; end; procedure TMyObjectList.SaveToFile(FileName:String); var Stream : TFileStream; begin // Erzeugen einer leeren Datei Stream:= TFileStream.Create(FileName, fmCreate); // Aufruf von SaveToStream, da alle notwendigen Funktionen hier schon // definiert wurden SaveToStream(Stream); // Freigabe des Streams Stream.Free; end; end.
Marco
Wer Rechtschreibfehler findet, der darf sie behalten Carpe Diem - Nutze den Tag (und zwar den ganzen!) |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |