AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

TComponents handhaben

Ein Thema von Mikkey · begonnen am 16. Sep 2014 · letzter Beitrag vom 17. Sep 2014
Antwort Antwort
Seite 1 von 2  1 2   
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#1

TComponents handhaben

  Alt 16. Sep 2014, 16:03
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:
var owner: TOwner; member: TMEmber;
...
owner = TOwner.Create(0);
member = TMember.Create(owner);
...
owner.Free();
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
DestroyComponents(); enthalten ist.

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

Geändert von TBx (17. Sep 2014 um 07:40 Uhr) Grund: Schreibfehler korrigiert
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.003 Beiträge
 
Delphi 2009 Professional
 
#2

AW: TComponents handhaben

  Alt 16. Sep 2014, 16:17
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
DestroyComponents(); enthalten ist.
Im Destruktor muss inherited (Destroy) aufgerufen werden. Andernfalls wird es auch in Delphi nicht wie erwartet funktioniere. Der Destruktor wird (in Delphi) mit override deklariert.

Hope this helps,
Michael Justin
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.534 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TComponents handhaben

  Alt 16. Sep 2014, 16:29
Wenn man die Klassenvervollständigung nutzt, geschieht das sogar automatisch

[edit] Um etwas genauer zu werden: ich habe mal diese Klassen deklariert
Delphi-Quellcode:
type
  TOwner = class(TComponent)
  public
    destructor Destroy; override;
  end;

  TMember = class(TComponent)
  public
    destructor Destroy; override;
    procedure SayHello;
  end;
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:
Delphi-Quellcode:
{ 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;
Nun noch ein kleiner Test:
Delphi-Quellcode:
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;
[/edit]
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen

Geändert von DeddyH (16. Sep 2014 um 16:45 Uhr)
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#4

AW: TComponents handhaben

  Alt 16. Sep 2014, 17:11
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:
DestroyComponents();
nicht zu einem Fehler, ich hätte darauf nur gern verzichtet, wenn TComponent das doch selbst machen soll.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#5

AW: TComponents handhaben

  Alt 16. Sep 2014, 17:22
Es geht zwar um ein Projekt in C++ (XE), aber ich denke/gehe davon aus, dass das Verhalten in Delphi dasselbe sein sollte.
Das scheint dann aber ganz offensichtlich nicht der Fall zu sein, obwohl ich das eigentlich auch erwartet hätte.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#6

AW: TComponents handhaben

  Alt 16. Sep 2014, 17:34
Dann nehme ich wenigstens mit, dass es in Delphi das tut, was ich erwarte
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.093 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: TComponents handhaben

  Alt 16. Sep 2014, 18:13
Dann zeig doch mal ein bisschen Code- Ich kann das nicht nachvollziehen: Wie auch in Delphi ist die Reihenfolge
  1. ~TOwner
  2. Geerbter TComponent-Destruktor: Ruft TComponent.DestroyComponents() auf
  3. Diese Methode zerstört die TMember-Instanz
  4. ~TMember

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;
}
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#8

AW: TComponents handhaben

  Alt 16. Sep 2014, 18:45
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.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.093 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: TComponents handhaben

  Alt 16. Sep 2014, 19:02
Ich verstehe nicht
  • Wie, der Debugger stoppt? Exception? Mit F7 kommst du eigentlich danach in den übergeordneten Destruktor ~TComponent...
  • Welches DestroyComponent auskommentiert? Die Delphi RTL verändert? DestroyComponents musst du nicht selbst aufrufen...
  • Welche C++ Builder-Version ist das denn überhaupt?
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#10

AW: TComponents handhaben

  Alt 16. Sep 2014, 22:24
Da ich Interfaces (anstelle von Sätzen von Rückruffunktionen) verwenden möchte, sind alle eigenen Klassen von TComponent abgeleitet.
Hier fängt das Problem schon an.
Nur weil man Interfaces implementieren möchte bedeutet das noch lange nicht dass man von TComponent ableiten sollte.
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 IInterface bzw. IUnknown implementieren und besser als Ausgangspunkt geeignet sind: TAutoIntfObject,TAutoObject,TComObject,TInterfaced Object
Je nach Anwendungszweck wählt man die passende Basisklasse.
fork me on Github

Geändert von TBx (17. Sep 2014 um 07:41 Uhr) Grund: zitierten Schreibfehler korrigiert
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es 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

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz