![]() |
Re: Wann Destruktor-Aufruf nötig?
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 |
Re: Wann Destruktor-Aufruf nötig?
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?
|
Re: Wann Destruktor-Aufruf nötig?
Zitat:
Zitat:
Delphi-Quellcode:
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.
constructor TTest.Create;
begin inherited Create; FFeld := wert; ... FStringList := TStringList.Create; // <-- ... end; 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 |
Re: Wann Destruktor-Aufruf nötig?
Zitat:
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? |
Re: Wann Destruktor-Aufruf nötig?
ö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? ;-) |
Re: Wann Destruktor-Aufruf nötig?
Zitat:
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 |
Re: Wann Destruktor-Aufruf nötig?
Zitat:
Delphi-Quellcode:
Faustregel 1:
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;
Code:
Faustregel 2:
Was Du erzeugst musst Du auch wieder zerstören
Code:
Vor jedem erneuten Create die Methode Free aufrufen
|
Re: Wann Destruktor-Aufruf nötig?
Zitat:
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 :wink: |
Re: Wann Destruktor-Aufruf nötig?
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 |
Re: Wann Destruktor-Aufruf nötig?
Zitat:
@ 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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:05 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