![]() |
Wie verwendet man "Unterklassen" am besten?
Hallo zusammen,
ich habe bisher eine mit einer Tlist einige Dateiinformationen verwaltet
Delphi-Quellcode:
Um mir das ewige Typecasting zu erparen hab ich daraus eine Klasse(TMyFiles) gemacht, wobei
type
tFileRec=record name : string; ext : string; path : string; size : cardinal; lastrd : tdatetime; lastwr : tdatetime; end; pFileRec = ^tFilerec; .Add und .Items[i] jeweils tFileRec erwartet bzw. liefert, aber FileList[i] gibt einen Pointer zurück. Wenn ich bisher z.B. mit allen .PAS Dateien etwas machen wollte ging das so ganz gut:
Delphi-Quellcode:
Danach waren noch alle (Datei)Daten in der allFileList vorhanden, und ich konnte ohne erneutes Einlesen z.B. alle XLS-Dateien verarbeiten.
pasFileList:=TList.Create;
if tFileRec(allFileList[i]^).ext='PAS' then pasFileList.add(allFileList[i]) .... { machwas } tFileRec(pasFileList[i]^).Name..... { machwas Ende} pasFileList.Free; { Kann ich das auch mit TMyFiles erreichen ohne die Krücke Typecasting und Tlist zu nutzen? Bräuchte ich ggf. zwei Free-Methoden? eine um die Nutzdaten (records) frei zu geben und eine um die Pointer in den Orcus zu schicken? Könntet Ihr mir hier auf die Sprünge helfen? |
AW: Wie verwendet man "Unterklassen" am besten?
Wird ein Record nicht automatisch freigegeben? Natürlich nicht, wenn du einen Pointer da was mit New zugewiesen hast.
Und ich verstehe dein aktuelles Problem nicht so ganz: Du hast ein TMyFiles was intern eine TList speichert, und du greifst munter mit add und so drauf zu? Dann kannst du doch alles so lassen oder nicht? MfG Fabian |
AW: Wie verwendet man "Unterklassen" am besten?
Aus dem Record eine Klasse machen und statt einem Array oder TList die Klasse TObjectList verwenden.
Delphi-Quellcode:
Leider gibt es viele Delphi-Programierer die den Schritt vom Record zur Klasse nicht vollziehen.
tFileObj=class(TPersistent)
public name : string; ext : string; path : string; size : cardinal; lastrd : tdatetime; lastwr : tdatetime; function Filename:string; // liefert name + ext function FullFilename:string; // liefert path + Filename procedure LoadFromSearchRec(const sr:TSearchRec); // kopiert Werte aus sr auf name,exe,size,... procedure Assign(Source: TPersistent);override; // sollte man implementieren end; Ich vermute, dass es unter anderem daran liegt, dass man Objekt explizit freigeben muss. Wobei hier aber TObjectList zur Hilfe kommt und die Sache angenehmer macht. |
AW: Wie verwendet man "Unterklassen" am besten?
Das mit der TObjectlist muß ich mir mal anschauen.
Trotzdem hab ich da immer noch ein Verständnisproblem. Ich habe eine Klasse die Verwaltungsdaten und die eigentlichen Daten enthält, und eine zweite Klasse, die nur die Verwaltungsdaten enthält (enthalten soll). So etwas ähnliches wie ein View oder ein Filter. Nach aussen hin sollen sich beide gleich verhalten, wobei die zweite Klasse die erste zwangsläufig vorraussetzt. wenn ich die zweite Klasse "in den Orcus jage" muß die erste allerdings vollständig erhalten bleiben. Tut mir leid, das ich es nicht besser beschreiben kann . Mir fehlt das richtige Vokabular. Gruß K-H PPs Ich schlepp noch ein paar Felder mehr mit mir herum, und da stecken noch einige Methoden in der Klasse. P.S. Zitat:
|
AW: Wie verwendet man "Unterklassen" am besten?
Du willst doch das TypeCast loswerden ... oder irre ich mich da?
|
AW: Wie verwendet man "Unterklassen" am besten?
Zitat:
K-H |
AW: Wie verwendet man "Unterklassen" am besten?
Du bist mit der TList vermutlich wirklich etwas zu kurz gesprungen. 8-) Wie gesagt : TobjectList und OwnsObjects sollte auf true stehen.
@Daniel : wäre gut, wenn man beim Schreiben sehen könnte, welche Delphi-Version eingesetzt wird. So, der ganze Krempel, den man in die TObjectList packt, wird dann beim free der Liste auch komplettt weggeräumt. Das ist minimaler Aufwand. Du kannst ja sogar auch die Records komplett in die ObjectList packen. Die schluckt fast alles. :shock: Hier mal noch, wie das ganze ungefähr aussieht :
Delphi-Quellcode:
Ist das Letzte ein Typecast ? :gruebel: Die Nomenklatur ist da etwas ungenau. 8-) Nenne man das Konstukt, wie man will. Mir ists egal, weil es einwandfrei funktioniert ohne Nachteile.
TArtGrundDaten = record
ID, nr : Integer; bez : string; // stark verkürzt !! end; TDatenObjekt = class(TObject) GrundDaten : TArtGrundDaten; end; DatenObjektListe : TObjectList; // nimmt spezif. Daten von TDatenObjekt auf for i := 0 to DatenObjektListe.Count - 1 do ArtAusgObjekt := TArtAusgObjekt (AusgObjektListe.Items[i]); Am Beispiel sieht man jedenfalls, wie man starre Records und Klassen kombinieren kann. Die Klassen, die den Record enthalten, werden an anderen Stellen jedenfalls noch OOP-mässig erweitert. |
AW: Wie verwendet man "Unterklassen" am besten?
Moin,
Zitat:
Zitat:
![]() Übrigens wenn ich das richtig verstehe würde ich das so in der Art machen:
Delphi-Quellcode:
Alternativ könnte man auch TFile von TMetaData erben lassen. Dürfte glaub ich besser sein.
TMetaData = class(TObject)
Name : string; [...] end; TFile = class(TObject) MetaData : TMetaData; Data : TStream; // Oder TMemoryStream end; MfG Fabian PS: Ich würde das letzte als Typecast ansehen. Weil was ist, wenn du irgendwas anderes reinkloppst. Deshalb würde ich entweder Generics verwenden (gibts leider nicht für D7) oder halt das Kapseln. |
AW: Wie verwendet man "Unterklassen" am besten?
Hallo,
Zitat:
Bis bald Chemiker |
AW: Wie verwendet man "Unterklassen" am besten?
Zitat:
Zitat:
Irgendwann kam dann mal irgendwer auf die Idee, dass die Datensätze sowieso gelesen, geschrieben oder sontwas werden müssen. Wieso sollte man eigentlich den Datensätzen nicht gleich sagen, was sie machen können ? Die reinen Daten, also Records hatten plötzlich die Möglichkeit auch "Methoden" zu haben. Das wären dann die heutigen TObject, TClass etc. Typen. Zurück zur Ausgangsfrage : es geht um Dateiname, Dateigroesse usw., also um ungefähr das, was TSearchRec sowieso hat. Man beachte auch das "Rec" im Namen. In meinem Beispiel benutze ich auch einen Record. Allerdings innerhalb der TObjectList. Diese kriegt notfalls noch Methoden verpasst. Der Record ist starr und braucht keine Methoden. xZise verwendet in seinem Bsp. TObject, obwohl er dafür gar keine Methoden braucht. Da würde es auch ein Record tun. Gut, das dürfte vernachlässigbaren Speicher-Mehrbedarf/Laufzeit bedeuten, im Prinzip aber auch nur Peanuts. 100 Bytes, 1 Millisekunde mehr, was solls ? Allerdings : Record ist mehr oder weniger egal. Wenn das OwnsObjects der TObjectList auch einiges (besser gesagt : sehr viel) selber erledigt, die TObject-Dinger muss ich trozudem mit create erzeugen, was bei Records überflüssig ist. |
AW: Wie verwendet man "Unterklassen" am besten?
Hallo Hansa,
die Records musst Du doch auch erstellen. Bis bald Chemiker |
AW: Wie verwendet man "Unterklassen" am besten?
Inwiefern muss ich die wo erstellen ? :shock: Oder gibts jetzt sogar so was wie Rec1.Create () ? Ich sage doch auch nicht Int1.Create oder Real2.Free.
|
AW: Wie verwendet man "Unterklassen" am besten?
Delphi-Quellcode:
Natürlich nur bei Zeigern nötig :wink:
var
rec: ^Recordtyp; begin New(rec); ... rec^.Feld := ...; // evtl. geht auch: (zumindest beim FPC) rec.Feld := ...; ... Dispose(rec); end; |
AW: Wie verwendet man "Unterklassen" am besten?
Zitat:
Und warum habe ich das mit Klassen gemacht? Ich frage mich nämlich wie du neue Einträge in die ObjectList bekommen willst:
Delphi-Quellcode:
Das heißt irgendwo muss du Datei reinitialisieren. Das macht man i.d.R. mithilfe von new oder einer Methode (also wie bei bei der Methode Rect()). Ersteres hat den Nachteil: TObjectList wird das Objekt vermutlich nicht freigeben (korrigiert mich, wenn das nicht stimmt). Bei zweiteren, hast du ja ausgeführt, dass das ja eigentlich eine Methode der Datei ist, dann kann man das auch gleich zum Objekt machen.
var
datei : TArtGrundDaten; list : TObjectList; list := TObjectList.Create(); datei.name := 'foobar'; list.add(datei); datei.name := 'Hallo Welt'; list.add(datei); UND inzwischen geht ja auch das:
Delphi-Quellcode:
Und dann hatte ich auch erwähnt, dass man TFile von TMetaData erben lassen kann. Das geht bei records nicht.
type
TFoo = record x : integer; function getXsqr() : Integer; end;
Delphi-Quellcode:
MfG
type
TMetaData = class; TFile = class(TMetaData) Data : TStream; end; Fabian |
AW: Wie verwendet man "Unterklassen" am besten?
Um das Typecasting komplett zu vermeiden, kann man generische Listen verwenden, aber die gibt es bei Delphi 7 nicht.
Ich benutze sowohl Records als auch Klassen. Die Entscheidung welches Konstrukt ich verwende, hängt vom Anwendungsfall ab. Dabei berücksichtige ich die Vorteile die die Strukturen jeweils bieten: Vorteile Records:
Zurück zur Ausgangsfrage: Um das Typcasting einzuschränken, würde ich bei TMyFile die Get-Funktion ändern. Etwa so:
Delphi-Quellcode:
Das Typecasting ist dann nur einmal in "Get" bzw. "Put" notwendig. Der Zugriff sieht dann so aus:type TMyFiles = class private FList: TList; public property Items[Index: Integer]: pFileRec read Get write Put; default; end;
Delphi-Quellcode:
Der Klasse TMyFiles ist es jetzt egal, ob sie "Besitzer" der Records ist, oder ob sie nur Verweise auf die Records verwaltet. Beim Freigeben muss man natürlich unterscheiden, ober man nur die Verweise freigeben will, oder auch die Records. Das kann man dann so machen, wie TObjectlist (ein Boolean zeigt an, was freigeben werden soll) oder man kümmert sich in jedem Einzelfall selbst darum.
var
allFileList: TMyFiles; ... if allFileList[i].ext='PAS' then N.B. Die Add Funktion muss natürlich auch noch entsprechend geändert werden (statt TFileRec nun pFileRec), oder man erfindet eine neue Funktion AdRef(file: pFileRec) oder wie auch immer... |
AW: Wie verwendet man "Unterklassen" am besten?
Wieso verwendet man nicht:
Delphi-Quellcode:
Typensicher, kein TypeCasting, kein Create, kein Free.
MyFileList : Array Of TFileinfoRecord;
|
AW: Wie verwendet man "Unterklassen" am besten?
Aber gerade das befüllen ist ziemlich langsam.
MfG Fabian |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:14 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 by Thomas Breitkreuz