Form schliessen und zerstören

Rund um die LCL und andere Komponenten
Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2261
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.8, FPC 3.0.4)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Form schliessen und zerstören

Beitrag von m.fuchs »

m.fuchs hat geschrieben:
Sa 2. Mai 2020, 21:11
wp_xyz hat geschrieben:
Sa 2. Mai 2020, 15:48
Während ich früher auch immer alles mögliche auf Nil gesetzt habe, hat mich ein Artikel von Nick Hodges (finde ich gerade nicht) nachdenklich gemacht. Denn es hilft, Probleme zu verschleiern. Wenn ich ein Objekt zerstöre und später daraufzugreife, habe ich einen Absturz. Aber wenn ich das Objekt zerstöre und die Variable auf nil setze, und beim späteren Zugriff auf Nil prüfe, läuft alles - bis vielleicht auf irgendwelche ominösen Fehler, die manchmal auftreten und schwer zu finden sind.
Hm, irgendwie fällt mir da nicht so wirklich ein Beispiel ein, wo das FreeAndNil so ein Problem erzeugt. Hast du zufällig eines da?
So, hab mir jetzt den Artikel mal durchgelesen. Ich lese daraus, dass FreeAndNil keine Probleme verschleiert, aber trotzdem nicht benutzt werden sollte, weil bei gutem Design keine Notwendigkeit dafür besteht. Sprich: wenn es tatsächlich nötig ist, dann hat man ein schlechtes Design.

Ich muss gestehen, ich habe bis jetzt konsequent FreeAndNil benutzt, wenn ich aber so in meinen Quellcode schaue sehe ich da keinerlei Grund für. Könnte ich eigentlich wirklich darauf verzichten.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Mathias
Beiträge: 4899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Form schliessen und zerstören

Beitrag von Mathias »

fliegermichl hat geschrieben:
Sa 2. Mai 2020, 22:34
FreeAndNil ist natürlich kein Allheilmittel.
Beispiel

Code: Alles auswählen

var a, b : TMyObject;
begin
 a := TMyObject.Create;
 b := a;
 // Jetzt zeigen sowohl a als auch b auf die neu erzeugte Instanz
 FreeAndNil(a);
 // die Instanz wurde freigegeben und a ist jetzt auch nil. b zeigt aber immer noch auf den Speicher, auf dem die Instanz früher mal war.
end;
Das ist ein ganz gemeiner.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 3265
Registriert: Fr 8. Apr 2011, 09:01

Re: Form schliessen und zerstören

Beitrag von wp_xyz »

m.fuchs hat geschrieben:
Sa 2. Mai 2020, 22:40
So, hab mir jetzt den Artikel mal durchgelesen. Ich lese daraus, dass FreeAndNil keine Probleme verschleiert
Ich denke schon, dass er das sagt:
Third, one of the justifications for using FreeAndNil is that it is defensive and that it protects against using a pointer at the wrong time. The claim is that if a pointer is nil, and you then use that pointer, then you’ll know right away, and the bug would be easy to find. Thus, if you feel the need to use FreeAndNil to ensure that you don’t misuse a pointer somewhere, then it is very likely you have a design problem: the scope of the pointer in question is larger than the use of that pointer in your code. Or, in other words, the scope of a pointer and the scope of the use of that pointer aren’t the same and they should be. If they aren’t , you are simply begging for trouble.
Auch: https://community.idera.com/developer-t ... your-enemy

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 597
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Winux (L 2.0.7 FPC 3.04)
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Form schliessen und zerstören

Beitrag von fliegermichl »

Das ist manchmal leichter gesagt als getan,

ich arbeite seit über 20 Jahren an einem CAD Programm das mittlerweile über eine halbe Mio Codezeilen hat. Ich habe von Anfang an so gut es geht versucht, alle Funktionalitäten in eigenen Klassen zu kapseln und die Oberfläche streng getrennt von der Funktionalität zu halten.

Ich habe so etwas ähnliches wie den Objektinspektor, wo die Gebäude, Dach-/Wandflächen, Linien und Punkte mit ihren Eigenschaften dargestellt werden. Das ganze basiert auf dem VTV.

Wo verwaltet man denn nun am besten seine Objektstrukturen? Wenn ich ein Gebäude zum Inspektor hinzufüge, bekommt die Node einen Userpointer auf das Gebäude.
Ebenso dessen Flächen und deren Punkte.

Das Gebäude selbst hält aber natürlich auch eine Liste aller seiner Flächen und jede Fläche hält eine Liste aller ihrer Punkte.
Die Linien hingegen gehören nur manchmal zu einer einzelnen Fläche. Manchmal sind es auch Verbindungen zwischen zwei verschiedenen Flächen des gleichen Gebäudes, manchmal aber auch Verbindungen zwischen Flächen verschiedener Gebäude.

Also halte ich die Verbindungskanten als eine Pointerliste im Projekt und jede Kante wiederum hat einen Zeiger auf ihre eine oder eben auch zwei Flächen.

Wo ist jetzt out of Scope?
Das geschickteste wäre so etwas wie FreeNotification in TComponent zu implementieren. Daran hatte ich am Anfang leider nicht gedacht und es im nachhinein reinzufrickeln würde vermutlich dazu führen, daß man es an hundert Stellen übersieht.

Vermutlich würde aber ein einfaches Object.Free einen schneller an die Stelle führen wo der Fehler sitzt.

Antworten