AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wann Destruktor-Aufruf nötig?

Ein Thema von Cöster · begonnen am 26. Okt 2006 · letzter Beitrag vom 28. Okt 2006
Antwort Antwort
Seite 2 von 3     12 3      
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#11

Re: Wann Destruktor-Aufruf nötig?

  Alt 27. Okt 2006, 09:12
Hallo,

ich schreibe immer einen constructor,
auch wenn der nur inherited Create aufruft.

1. jede Klasse wird mal erweitert
2. weit wichtiger, da ich memcheck
benutze, zeigt er mir genau die Stelle, wo die Klasse erzeugt wird,
aber nicht mehr freigegeben wird.
3. siehe oben (das mit der neuen Basisklasse)


Heiko
Heiko
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#12

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 09:48
Nun hab ich das Problem, dass beim Zurücksetzen der Eigenschaften einige Instanzen bereits zerstört sind, andere nicht. Dann funktioniert eine Methode wie Clear natürlich nicht. Sollte ich dann doch alle Objekte wieder neu erstellen? Hab ich Beitrag #3 richtig verstanden, dass ich vor dem erneuten Create nicht erst Destroy aufzurufen brauche?
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#13

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 11:07
Zitat von Cöster:
Nun hab ich das Problem, dass beim Zurücksetzen der Eigenschaften einige Instanzen bereits zerstört sind, andere nicht. Dann funktioniert eine Methode wie Clear natürlich nicht.
Mach mal n Beispiel. Weiß nicht so ganz, wie du das meinst...

Zitat:
Sollte ich dann doch alle Objekte wieder neu erstellen? Hab ich Beitrag #3 richtig verstanden, dass ich vor dem erneuten Create nicht erst Destroy aufzurufen brauche?
Ähm... bitte nicht zum Eigenschaften zurücksetzen Create aufrufen. Schreib dir lieber ne Methode Reset oder sowas... Warum? Manchmal geht das gut, jo. Wenn aber sowas im Konstruktor steht, produzierst du Speicherlöcher:
Delphi-Quellcode:
constructor TTest.Create;
begin
  inherited Create;
  FFeld := wert;
  ...
  FStringList := TStringList.Create; // <--
  ...
end;
Warum sollte man nun trotzdem Speicher freigeben, auch, wenn der Speichermanager hinterher wieder aufräumt? Ganz einfach: Du kippst doch auch nicht deinen Mülleimer aus dem Fenster, nur, weil du weißt, dass irgendwann jemand kommt, der das aufräumt... Es ist einfach schlechter Programmierstil.

Unter .NET is das was anderes: Da is die Putzfrau schon bestellt um nach der virtuellen Party die verloren gegangenen Bits wieder zusammenzukehren...

mfg

Chriostian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#14

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 11:34
Zitat von r2c2:
Zitat von Cöster:
Nun hab ich das Problem, dass beim Zurücksetzen der Eigenschaften einige Instanzen bereits zerstört sind, andere nicht. Dann funktioniert eine Methode wie Clear natürlich nicht.
Mach mal n Beispiel. Weiß nicht so ganz, wie du das meinst...
16 Objekte werden in einer von TObjectList abgeleiteten Klasse verwaltet. Während das Programm läuft, wird gelegentlich ein Objekt aus der ObjektList per Delete gelöscht. Wenn auf btnNeu geklickt wird, sollen sich wieder alle 16 Objekte in der ObjektList befinden und die Eigenschaften sollen zurückgesetzt werden. Es soll also wieder genau der Stand vom Anfang zurückgestellt werden.

Mit der Methode Clear meinte ich die von das von dir angesprochene Reset, hab's nur Clear genannt, weil Hoika es in Beitrag #2 so genannt hatte. Ich kann aber ja schlecht Reset für ein Objekt aufrufen, welches bereits gelöscht wurde. Dieses Objekt müsste ich erst wieder neu erstellen.

Deswegen wollte ich gleich alle Objekte neu erstellen. Haltet ihr es für geschickter, zu prüfen, welche Objekte noch bestehen und für diese Reset aufzurufen und nur die anderen zu createn?
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#15

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 11:38
öhm ...
Also wenn Du ein Objekt aus der Liste löschst, solltest Du erst dessen .Free-Methode aufrufen und es dann tatsächlich aus der Liste entfernen. Diese hat danach eben ein Element weniger.

Und wenn Du wieder auf 16 Elemente kommen möchtest, dann füllst Du eben auf. Aber auf diese Weise bist Du sicher, dass die Elemente, die noch in der Liste sind, definitiv auch benutzbar sind. Alles Andere wäre aus meiner Sicht softwaretechnische Kamikaze.

Wie merkst Du Dir denn jetzt, auf welche Positionen Du noch zugreifen kannst und auf welche nicht? Oder vertraust Du auf das Glück des Anwenders?
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
r2c2

Registriert seit: 9. Mai 2005
Ort: Nordbaden
925 Beiträge
 
#16

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 11:40
Zitat von Cöster:
Deswegen wollte ich gleich alle Objekte neu erstellen. Haltet ihr es für geschickter, zu prüfen, welche Objekte noch bestehen und für diese Reset aufzurufen und nur die anderen zu createn?
Kommt drauf an, wie viele Objekte das sind:
Hast du noch viele Objekte da, isses schneller diese zurückzusetzen, hast du wenige, isses schneller alle neu zu erstellen.

In Anbetracht dessen, dass du nur ObjectList.Clear; aufrufen musst(OwnsObjects ist true) um alle Objete frei zu geben, und du das Erstellen aller objekte in ne separate Prozedur packen kannst, isses aber wohl deutlich einfacher alles neu zu erstellen...

mfg

Christian
Kaum macht man's richtig, schon klappts!
  Mit Zitat antworten Zitat
Benutzerbild von Jens Schumann
Jens Schumann

Registriert seit: 27. Apr 2003
Ort: Bad Honnef
1.644 Beiträge
 
Delphi 2009 Professional
 
#17

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 11:41
Zitat von Cöster:
Hab ich Beitrag #3 richtig verstanden, dass ich vor dem erneuten Create nicht erst Destroy aufzurufen brauche?
Wenn Du ein Objekt erzeugt hast mußt Du grundsätzlich vor einem erneuten Create den Destructor aufrufen. Der Destructor wird über die Methode Free aufgerufen. Wenn Du das nicht machst produzierst Du Speicherlöcher!!!
Delphi-Quellcode:
Beispielprocedure TForm1.Button1Click(Sender: TObject);
var
  MyList : TStrings;
begin
1. MyList := TStringlist.Create; // Hier wird das Objekt MyList erzeugt und belegt Arbeitsspeicher
                                  // In MyList wird eine Referenz (Zeiger) auf den reservierten
                                  // Arbeitsspeicher abgelegt.
2. MyList.Add('Test');
3. MyList := TStringlist.Create; // Hier wird ebenfalls das Objekt MyList erzeugt und belegt Arbeitsspeicher
                                  // Was passiert aber mit dem unter 1. reservierten Arbeitsspeicher?
                                  // Gar nichts. Der Arbeitsspeicher wird durch das Create unter 3. weder
                                  // freigeben noch überschrieben. D.h. der Arbeitsspeicher bleibt reserviert und belegt
                                  // Da jetzt durch 3. MyList einen anderen Arbeitsspeicherblock referenziert ist der
                                  // Arbeitsspeicher von 1. für Dein Programm nicht mehr erreichbar und bleibt bis zum
                                  // Programmende belegt.
4. MyList.Add('Delphipraxis');
end;
Faustregel 1:
Code:
Was Du erzeugst musst Du auch wieder zerstören
Faustregel 2:
Code:
Vor jedem erneuten Create die Methode Free aufrufen
I come from outer space to save the human race
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#18

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 12:11
Zitat von Daniel:
Wie merkst Du Dir denn jetzt, auf welche Positionen Du noch zugreifen kannst und auf welche nicht? Oder vertraust Du auf das Glück des Anwenders?
Bei Delete wird doch Count um 1 verringert und alle Elemente 1 nach vorne gesetzt, oder? In allen meinen Schleifen hab ich stehen for I := 0 to Count - 1. Ich dachte eigentlich, dass dadurch alles glatt laufen würde. Aber komischerweise kommt trotzdem immer eine "Exception der Klasse EListError mit der Meldung 'Listenindex überschreitet das Maximum (15)'". Irgendwas mach ich da falsch. Ich weiß aber auch nicht, wo genau der Fehler auftritt, denn der Cursor wird nicht in die Zeile des Fehlers gesetzt, sondern an die Stelle, wo die Prozedur aufgerufen wird, innerhalb der der Fehler entsteht. Kann man das irgendwie irgendwo anders einstellen?

Inzwischen denke ich mir aber, vielleicht geb ich den Objekten ne Boolean-Eigenschaft, unter der ich speicher, ob mit dem Objekt noch etwas gemacht werden soll. Dann behalte ich immer meine 16 Objekte und könnte auch später bequem die Reset-Methode aufrufen.

Aber wie das mit dem Delete genau funzt, würde mich trotzdem interessieren.

@ Jens Schumann: Danke, die Faustregeln werd ich mir merken
  Mit Zitat antworten Zitat
Hawkeye219

Registriert seit: 18. Feb 2006
Ort: Stolberg
2.227 Beiträge
 
Delphi 2010 Professional
 
#19

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 12:32
Hallo Cöster,

wenn du innerhalb einer Schleife Elemente aus einer Liste (TList, TObjectList,...) entfernen möchtest, solltest du die Schleife rückwärts laufen lassen. Da beim Löschen die Listenlänge verändert wird, greifst du sonst bei den letzten Schleifendurchläufen auf nicht mehr gültige Elemente zu. Der Schleifenendwert wird vor dem Start der Schleife ermittelt und durch das Löschen nicht verändert.

Gruß Hawkeye
  Mit Zitat antworten Zitat
Cöster

Registriert seit: 6. Jun 2006
589 Beiträge
 
Turbo Delphi für Win32
 
#20

Re: Wann Destruktor-Aufruf nötig?

  Alt 28. Okt 2006, 12:54
Zitat von Daniel:
Also wenn Du ein Objekt aus der Liste löschst, solltest Du erst dessen .Free-Methode aufrufen
Passiert das bei einer TObjectList nicht automatisch, wenn OwnsObjects wie voreingestellt auf True gesetzt ist?

@ Hawkeye219: Ah, klingt logisch, das war auch der Fehler. Wundert mich nur, dass der Cursor beim Auftreten des Fehlers immer zu dem Aufruf einer anderen Methode gesprungen ist, in der der Fehler dann gar nicht aufgetreten ist.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 15:50 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