Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - eigene Klasse als Property einer eigenen Klasse
Zero5 - Fr 18.02.05 17:50
Titel: eigene Klasse als Property einer eigenen Klasse
Hi,
ich habe eine Klasse:
Delphi-Quelltext
1:
| TID3 = class(TPersistant) |
mit dieser Property (nur kategorisch deklariert):
Delphi-Quelltext
1: 2:
| property XXXComment: TXXX; |
TXXX ist eine Klasse:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| TXXX = class(TObject) private FDiscriptor: TStringList; FContent: TStringList; FOwner: TID3; procedure SetDiscriptor(Value: TStringList); procedure SetContent(Value: TStringList); public property Discriptor: TStringList read FDiscriptor write SetDiscriptor; property Content: TStringList read FContent write SetContent; constructor Create(Owner: TID3); end; |
Nun möchte ich die Klasse TXXX als Property von TID3 deklarieren, in der Weise, wie bspw. TListItems einem TListView als owner zugeordnet ist.
Ich hab nur keine Ahnung wie man das mit dem owner-Handling implementiert und bin auch trotz längerer Suche nirgends fündig geworden.
Wenn ich es wie hier gezeigt code, habe ich das Problem, dass der Compiler 'TXXX' nicht kennt, weil es ja erst später deklariert ist und andersherum funktioniert es wegem den Owner nicht.
Kann mir irgendwer helfen ?
Danke !
Gruß
Christian
Moderiert von
Motzi: Topic aus Algorithmen, Optimierung und Assembler verschoben am Fr 18.02.2005 um 17:01
Grendel - Fr 18.02.05 17:59
Stichwort: Forward-Deklaration!
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| type TXXX = class;
TID3 = class(TPersistent) ... public constructor Create(AOwner: TXXX); end;
TXXX = class(TObject) published property ID3: TID3 ... end; |
Bis neulich ...
edit: Ups! Sehe gerade, daß ich die Klassen verdreht habe. Prinzip ist aber das selbe.
Delete - Fr 18.02.05 18:00
Titel: Re: eigene Klasse als Property einer eigenen Klasse
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| TID3 = class; TXXX = class(TObject) private FDiscriptor: TStringList; FContent: TStringList; FOwner: TID3; procedure SetDiscriptor(Value: TStringList); procedure SetContent(Value: TStringList); public property Discriptor: TStringList read FDiscriptor write SetDiscriptor; property Content: TStringList read FContent write SetContent; constructor Create(Owner: TID3); end;
TID3 = class private public ... end; |
Oben schreibst du einfach nur diese eine Zeile und dann spielt die Reihenfolge keine Rolle mehr.
IngoD7 - Fr 18.02.05 19:19
Titel: Re: eigene Klasse als Property einer eigenen Klasse
Zero5 hat folgendes geschrieben: |
in der Weise, wie bspw. TListItems einem TListView als owner zugeordnet ist. |
Sollte nicht überhaupt erstmal die Eigenschaft XXXComment als Instanz der Klasse TXXX in TID3 eingebaut werden?
So grob etwa:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| TID3 = class(TPersistent) private FXXXComment : TXXX; public property XXXComment : TXXX read FXXXComment write SetXXXComment; constructor Create(Owner: TObject); override; end;
constructor TID3.Create(Owner: TObject); begin inherited Create(Owner); ... FXXXComment := TXXX.Create(Self); end; |
Der Constructor von TXXX sieht dann ungefähr so aus:
Delphi-Quelltext
1: 2: 3: 4: 5:
| constructor TXXX.Create(Owner: TID3); begin ... FOwner := AOwner; end; |
Ich bin zwar nicht der große Crack in diesen Dingen, aber
so ist auch die Eigenschaft Items vom Typ TListItems in TLiestView eingebaut.
Zero5 - Fr 18.02.05 22:20
Titel: Re: eigene Klasse als Property einer eigenen Klasse
Hi,
also erstmal Danke für die vielen Tips.
Hab´s jetzt so gemacht, und es funktioniert !
Mir ist nur noch nicht ganz klar, für was ich nun den owner brauch, bisher wird der nur in dem Feld Fowner gespeichert.
Was passiert bei der Freigabe von TID3, wird das das TXXX Objekt mit freigegeben (automatisch über den owner), oder muss ich das dem explizit sagen ?
Gruß
Christian
IngoD7 - Sa 19.02.05 00:00
Titel: Re: eigene Klasse als Property einer eigenen Klasse
Zero5 hat folgendes geschrieben: |
Hab´s jetzt so gemacht, und es funktioniert ! |
Wie denn? Wie ich es beschrieben hatte?
Zero5 hat folgendes geschrieben: |
Mir ist nur noch nicht ganz klar, für was ich nun den owner brauch, bisher wird der nur in dem Feld Fowner gespeichert. |
Mache in deiner Klasse TXXX ...
Delphi-Quelltext
1: 2:
| public property Owner:TID3 read FOwner; |
... und du kannst jederzeit über XXXComment.Owner abfragen, zu welcher Instanz von TID3 es gehört, bzw. darüber auf die Instanz von TID3 zugreifen. Dein Programm könnte ja mehrere Komponenten vom Typ TXXX behandeln. Zu was anderem als der Klärung des Eigentümers bzw. des Zugriffes auf ihn ist Owner in
diesem Falle nicht gut.
Aber mal ein Beispiel, wo es interessanter ist:
Wenn dein TID3 und TXXX von TComponent (oder Nachfahren davon) abgeleitet wären
und der Constructor von TXXX ein "inherited Create(Owner);" enthalten würde, so würde schlussendlich auch der Constructor von TComponent ausgeführt werden, welcher wiederum z.B. die Instanz von TXXX in die Komponentenliste (Eigenschaft Components) des Owners eintragen würde. Solche Mechanismen sind dann z.B. interessant, wenn eine Komponente seine Unterkomponenten kennen muss.
Das scheint bei dir aber nicht der Fall zu sein, weil deine Ableitung von TID3 weiter oben bei TPerstistent ansetzt und deinem TID3 (welche kaum als "Komponente" zu bezeichnen ist) dadurch die Eigenschaft Components fehlt. Davon (Ableitung von TPersistent) rät die Online-Hilfe im übrigen ab!
Zero5 hat folgendes geschrieben: |
Was passiert bei der Freigabe von TID3, wird das das TXXX Objekt mit freigegeben (automatisch über den owner), oder muss ich das dem explizit sagen ? |
Meines Wissens kann die automatische Freigabe nur geschehen, wenn - wie auch oben beschrieben - beide von TComponent (oder Nachfahren) abgeleitet sind. TListView hat in seinem Destructor auch eine expliziete Freigabe seiner Eigenschaft Items (Typ TListItems) eingebaut, weil TListItems kein Nachfahre von TComponent ist.
In deinem Falle müsste wohl ebenfalls auch der Destructor von TID3 overrided werden und dort ein FXXXComment.Free drin auftauchen.
Zero5 - Sa 19.02.05 00:59
Titel: eigene Klasse als Property einer eigenen Klasse
Hi,
sorry für die ungenaue Antwort !
So sieht´s jetzt aus:
Mir ist nur noch was bei setzen der Prop beim ID3 aufgefallen, hab ich kommentiert.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
| TXXX = class; TID3 = class(TPersistent) private FXXXComment: TXXX; procedure FSetXXXComment(NewXXX: TXXX); published property XXXComment: TXXX read FXXXComment write FSetXXXComment; end;
TXXX = class(TObject) private FDiscriptor: TStringList; FContent: TStringList; FOwner: TID3; procedure SetDiscriptor(Value: TStringList); procedure SetContent(Value: TStringList); public property Discriptor: TStringList read FDiscriptor write SetDiscriptor; property Content: TStringList read FContent write SetContent; constructor Create(Owner: TID3); end;
implementation
procedure TID3.Create FXXXComment := TXXX.Create(self); end;
procedure TID3.FSetXXXComment(NewXXX: TXXX); begin FXXXComment := NewXXX; end;
constructor TXXX.create(owner: TID3); begin FOwner := Owner; FDiscriptor := TStringList.Create; FContent := TStringList.Create; end;
procedure TXXX.SetContent(Value: TStringList); begin FContent.Assign(Value); end;
procedure TXXX.SetDiscriptor(Value: TStringList); begin FDiscriptor.Assign(Value); end; |
Gruß
Christian
IngoD7 - Sa 19.02.05 02:16
Vorab: Ich habe mein vorheriges Posting (das vor diesem hier) mehrfach geändert. :oops: Das Ergebnis ist dasselbe. Einzelne erklärende Passagen davor aber nicht mehr. Die waren zwischenzeitlich tlw. schlicht falsch. Sorry!
Nun einige Sachen, die mir aufgefallen sind:
Ja, das in der Procedure TID3.FSetXXXComment scheint soweit in Ordnung. Du solltest sie aber "SetXXXComment" nennen. Das "F" lässt man in dem Falle weg (Vereinbahrung). Wenn du in der Procedure nichts anderes machst als das, was da steht, dann brauchst du sie auch nicht. Dann könnte die Eigenschaft direkt so definiert werden:
Delphi-Quelltext
1:
| property XXXComment: TXXX read FXXXComment write FXXXComment; |
Man benutzt oft eine Proc an der Stelle, weil man dort gerne das unnötige Setzen der Variablen verhindert:
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TID3.SetXXXComment(NewXXX: TXXX); begin if FXXXComment <> NewXXX then FXXXComment := NewXXX; end; |
Ich habe kaum eine Ahnung wozu das gut sein soll. Ist aber so uso.
Den Constructor von TID3 solltest du auch "constructor" nennen und nicht "procedure".
Vergiss nicht die Destructoren von TID3 und TXXX. Es gibt dort einiges freizugeben (FXXXXComment bei TID3 und die beiden Stringlisten bei TXXX).
Zero5 - Mi 23.02.05 21:52
Titel: eigene Klasse als Property einer eigenen Klasse
Hi,
vielen Dank, hab ich jetzt so gemacht und funktioniert ganz gut !
Gruß
Christian
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!