![]() |
TComponents handhaben
Es geht zwar um ein Projekt in C++ (XE), aber ich denke/gehe davon aus, dass das Verhalten in Delphi dasselbe sein sollte.
Da ich Interfaces (anstelle von Sätzen von Rückruffunktionen) verwenden möchte, sind alle eigenen Klassen von TComponent abgeleitet. Ich verstehe die hier mit der Suche gefundenen Beiträge so, dass beim Zerstören eines TComponent-Objekts (owner) auch die TComponents (member) zerstört werden, die mit der Angabe owner erzeugt wurden:
Code:
TOwner <-- TComponent
TMember <-- TComponent
Delphi-Quellcode:
Ich würde eigentlich erwarten, dass beim Ausführen der letzten Zeile auch der Destruktor von TMember durchlaufen wird. Tatsächlich tut er das aber nur, wenn im Destruktor von TOwner der Aufruf
var owner: TOwner; member: TMEmber;
... owner = TOwner.Create(0); member = TMember.Create(owner); ... owner.Free();
Delphi-Quellcode:
enthalten ist.
DestroyComponents();
Die Komponenten sind keine Controls. Wäre nett, wenn mir jemand ein "ISSO!" oder "müsste eigentlich klappen" geben könnte - möglichst nicht beides ;) |
AW: TComponents handhaben
Zitat:
Hope this helps, |
AW: TComponents handhaben
Wenn man die Klassenvervollständigung nutzt, geschieht das sogar automatisch ;)
[edit] Um etwas genauer zu werden: ich habe mal diese Klassen deklariert
Delphi-Quellcode:
Nun den Cursor irgendwo in der TOwner-Klasse platziert und CTRL + SHIFT + C gedrückt, dann den Cursor in die TMember-Klasse und dasselbe noch einmal. Ich poste hier mal den gesamten Source, die ShowMessage-Aufrufe sind von mir, der Rest wurde automatisch generiert:
type
TOwner = class(TComponent) public destructor Destroy; override; end; TMember = class(TComponent) public destructor Destroy; override; procedure SayHello; end;
Delphi-Quellcode:
Nun noch ein kleiner Test:
{ TOwner }
destructor TOwner.Destroy; begin ShowMessage('Owner wird freigegeben'); inherited; end; { TMember } destructor TMember.Destroy; begin ShowMessage('Member wird freigegeben'); inherited; end; procedure TMember.SayHello; begin ShowMessage('Hallo vom Member'); end;
Delphi-Quellcode:
[/edit]
procedure TFormTest.Button1Click(Sender: TObject);
var Owner: TOwner; Member: TMember; begin Owner := TOwner.Create(nil); try Member := TMember.Create(Owner); Member.SayHello; finally Owner.Free; end; end; |
AW: TComponents handhaben
Leider hilft mir beides nicht weiter, denn
a) gibt es in C++ kein "inherited", der Destruktor der Basisklasse wird ohnehin implizit aufgerufen (lässt sich auch aus Vorsatz nicht verhindern) b) Strg+Shift+C tut im C++Builder ... nichts Glücklicherweise führt der manuell eingefügte
Code:
nicht zu einem Fehler, ich hätte darauf nur gern verzichtet, wenn TComponent das doch selbst machen soll.
DestroyComponents();
|
AW: TComponents handhaben
Zitat:
|
AW: TComponents handhaben
Dann nehme ich wenigstens mit, dass es in Delphi das tut, was ich erwarte :?
|
AW: TComponents handhaben
Dann zeig doch mal ein bisschen Code- Ich kann das nicht nachvollziehen: Wie auch in Delphi ist die Reihenfolge
Code:
#include <vcl.h>
#include <windows.h> #pragma hdrstop #pragma argsused #include <tchar.h> #include <stdio.h> class TOwner: public TComponent { public: __fastcall virtual ~TOwner() { (void)0; // Haltepunkt. Wird erreicht. } __fastcall virtual TOwner(TComponent* AOwner): TComponent(AOwner){}; }; class TMember: public TComponent { public: __fastcall virtual ~TMember() { (void)0; // Haltepunkt. Wird erreicht. } __fastcall virtual TMember(TComponent* AOwner): TComponent(AOwner){}; }; int _tmain(int argc, _TCHAR* argv[]) { TOwner *myOwner = new TOwner(NULL); TMember *myMember = new TMember(myOwner); myOwner->Free(); return 0; } |
AW: TComponents handhaben
Komischerweise stoppt der Debugger an den (void)0-Zeilen. Nachdem ich das betreffende Projekt wieder geladen habe und einen "DestroyComponent" auskommentiert habe, hat er im Destruktor der Member-Klasse ebenfalls angehalten. Die vorher generierten "nicht-gelöscht-Debugausgaben" sind ebenfalls nicht mehr da.
Dafür gibt's jetzt andere Fehler, das muss ich mir erstmal ansehen. Das ganze Projekt kann ich aus naheliegenden Gründen hier nicht einstellen, Teile wäre erst sinnvoll, wenn ich weiß, welche gebraucht werden. |
AW: TComponents handhaben
Ich verstehe nicht
|
AW: TComponents handhaben
Zitat:
Nur weil man Interfaces implementieren möchte bedeutet das noch lange nicht dass man von
Delphi-Quellcode:
ableiten sollte.
TComponent
Interfaces und TComponent haben völlig unterschiedliche Konzepte bezüglich der Lebenszeit der Objekte. Während Interfaces auf Referenzzählung setzen werden beim Tod eines "Königs" (die oberste Komponente, meist ein Formular oder Datenmodul) alle Untertanen sowie deren Untertanen destroyed. Komponenten bilden eine Baumstruktur wenn man einen Owner angibt. Weil Borland aber ActiveX-Controls unterstützen wollte musste man beide Konzepte unter einen Hut bringen. Das funktioniert aber naturgemäß nur unter Schwierigkeiten. Es gibt aber einige andere Basisklassen die ebenfalls
Delphi-Quellcode:
bzw.
IInterface
Delphi-Quellcode:
implementieren und besser als Ausgangspunkt geeignet sind: TAutoIntfObject,TAutoObject,TComObject,TInterfaced Object
IUnknown
Je nach Anwendungszweck wählt man die passende Basisklasse. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:46 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