Autor Beitrag
Zero5
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Fr 18.02.05 17:50 
Hi,

ich habe eine Klasse:

ausblenden Delphi-Quelltext
1:
TID3 = class(TPersistant)					


mit dieser Property (nur kategorisch deklariert):
ausblenden Delphi-Quelltext
1:
2:
  
property XXXComment: TXXX;


TXXX ist eine Klasse:

ausblenden 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 user profile iconMotzi: Topic aus Algorithmen, Optimierung und Assembler verschoben am Fr 18.02.2005 um 17:01
Grendel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 443

Gentoo Linux, MacOS X, Win 2000
D5 Ent, D7 Ent, Lazarus, Anjuta, MonoDevelop
BeitragVerfasst: Fr 18.02.05 17:59 
Stichwort: Forward-Deklaration!

ausblenden 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.


Zuletzt bearbeitet von Grendel am Fr 18.02.05 18:01, insgesamt 1-mal bearbeitet
Elite
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Fr 18.02.05 18:00 
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 629


D7
BeitragVerfasst: Fr 18.02.05 19:19 
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:
ausblenden 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Fr 18.02.05 22:20 
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 629


D7
BeitragVerfasst: Sa 19.02.05 00:00 
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 ...
ausblenden 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.


Zuletzt bearbeitet von IngoD7 am Sa 19.02.05 01:54, insgesamt 2-mal bearbeitet
Zero5 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Sa 19.02.05 00:59 
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.

ausblenden volle Höhe 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
   //Ist das so i.O. ? 
   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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 629


D7
BeitragVerfasst: 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:
ausblenden 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:
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 18

Win XP
D7 Ent
BeitragVerfasst: Mi 23.02.05 21:52 
Hi,

vielen Dank, hab ich jetzt so gemacht und funktioniert ganz gut !

Gruß
Christian