Re: Wo gebt ihr Objekte frei?
Moin Popov,
Zitat:
|
Re: Wo gebt ihr Objekte frei?
Was sind denn "gut programmierte Programme" bzw. Kriterien dafür?
|
Re: Wo gebt ihr Objekte frei?
Zitat:
Delphi-Quellcode:
Jetzt nicht das, aber irgendwas in der Richtung.
function BildLaden(FileName: TFileName): TBitmap;
begin Result := TBitmap.Create; Result.LoadFromFile(FileName); end; |
Re: Wo gebt ihr Objekte frei?
Hi,
eigentlich geht bei sauberer Programmierung kein Weg an Punkt 3 vorbei. Ansonsten kann ich nur absolut Christian S. zustimmen, hätte es nicht besser ausdrücken können :thumb: Die obere Function "Bild laden" ist in meinen Augen ein absolutes "no go"! Falls ich sowas im Source Code einer Bewerbung sehe, landet die schonmal im Papierkorb ! Dann eher:
Delphi-Quellcode:
Aber bei diesem Beispiel könnte man ja nach dem Code "aussen rum",
function BildenLaden(sFilename : TFilename; TargetBmp : TBitmap) : boolean;
begin result := false; if not Fileexist(sFilename) then exit; if not Assigned(TargetBmp) then exit; try TargetBmp.LoadfromFile(sFilename); result := true; except {} end; end; procedure bild_xyz; Var tmpBmp : TBitmap; begin tmpBmp := TBitmap.create; try if BildLaden(sFilename, tmpBmp) then BildAnzeigen(tmpBmp); finally FreeAndNil(tmpBmp);// oder tmpBmp.free end; end; auch eine eigene Klasse schreiben die das Bitmap als private var hat. In diesem Fall würde das Bitmap im Constructor erzeugt, im Destructor zerstört/freigegeben und die Klasse hätte die Methoden LoadFromFile, LoadFromStream, Clear Display etc. @arbu man: Wenn man sauber programmiert, dann brauch man den Garbage Collector nicht !!! ^^^^^^Ein Grund warum ich Java nicht mag und so gut wie gar nicht benutze. Ich möchte Speicher immer nur dann reservieren, benutzen wenn ich ihn brauche und wenn er nicht mehr benötigt wird, soll er auch umgehend freigegeben werden. Es ist zwar schön wenn Mann sich darum nicht kümmern muss und einfach "seinen Müll" vor die Tür stellt und wartet das er abgeholt wird. Nur umso schlimmer wenn die Müllabfuhr nicht oder zu spät kommt. Greetz DataCool |
Re: Wo gebt ihr Objekte frei?
Moin DataCool,
wobei ich da noch einen kleinen Verbesserungsvorschlag hätte: TargetBmp sollte besser als const deklariert werden. Es funktioniert zwar so auch, aber wenn mal jemand daran arbeitet könnte, ohne Compilerwarnung, etwas in den Parameter geschrieben werden, so dass man dann zum einen ein Speicherleck bekommen kann, und sich zum anderen erst einmal wundert, warum's nicht wie erwartet funktioniert. In einem anderen Thread hatte ich gerade gestern geschrieben, dass ich nur var- oder const-Parameter verwende. Var bei Rückgabewerten (die ggf. zu Beginn natürlich auch Eingabewerte enthalten können), const bei reinen Eingabewerten, oder wenn Referenzen übergeben werden sollen. Für Wert-Parameter habe ich bislang keine rechte Verwendung gefunden ;-) Zum Thema Garbage-Collection: Ich weiss nicht, wie gut die heutzutage implementiert ist, aber meinen Schneider Zeiten (CPC 464, Basic mit Garbage-Collection) war es immer eine mittlere Katastrophe, wenn die GC zugeschlagen hat. Der Rechner war dann immer für längere Zeit ausser Gefecht gesetzt, bis ihm wieder Reaktionen zu entlocken waren :mrgreen: Das sollte bei den heutigen Multi-Tasking-Systemen aber wohl kein Thema mehr sein. |
Re: Wo gebt ihr Objekte frei?
@DataCool: Eine leerer except Block ist aber genauso unsittlich und würde auch den Weg in den Papierkorb finden :wink:
Und FreeAndNil() auf lokale Variablen (und das noch im Finally-Block am Ende der Procedure) ist auch schon mehrfach diskutiert worden - mit unterschiedlichem Ergebnis. Zitat:
|
Re: Wo gebt ihr Objekte frei?
Alle drei Varianten sidn ok und von Fall zu Fall auch sinnig.
Meistens benutze ich Fall 3, manchmal Fall 2 und eher selten Fall 1. Zu Fall 1 noch eine Anmerkung. Ich finde, wenn man diese Variante benutzt sollte die Klasse, die das Objekt in seiner Methode zurückgibt auch eine Methode besitzen, um diese Objekt frezugeben.
Delphi-Quellcode:
function TEineKlasse.ErzeugeEinObject(): TEineAndereKlasse; begin ... end procedure TEineKlasse.GibObjectWiederFrei(); begin ... end; Wenn man ein Objekt erhält, daß nur einmal existieren darf, sorgt die Methode "GibObjectWiederFrei" dafür, daß genau dieses Objekt freigegeben wird. Hat man den Fall, daß diese Klasse immer wieder neue Objekte erzeugen kann, dann sollte die Klasse selbst eine Referenz zu jedem erzeugten Object in einer Liste halten und beim Aufruf von "GibObjectWiederFrei" könnte man dann entweder den Index des Objektes übergeben oder das Objekt selbst... Ich finde alle Varianten sind Geschmackssache und jedes hat seine Lebensberechtigung. Im normalen Programmieralltag wird man aber bevorzugt Variante 3, seltener Variante 2 und ganz selten Variante 1 benutzen. Ich und meine Kollegen machen das zumindest so. |
Re: Wo gebt ihr Objekte frei?
Mit so einer regen Diskussion hatte ich garnicht gerechnet. Ich habe alle Antworten gespannt durchgelesen und bin nun zu dem Schluss gekommen, dass wenn mehrere Programmierer an dem Projekt arbeiten sollen Variante 3 fast immer zu bevorzugen ist.
Ich hatte in einem Projekt vor kurzem den Fall, Variante 2 verwendet wurde und ich fälschlicherweise das Objekt freigegeben habe.
Delphi-Quellcode:
(TImage verwendet für dir Zuweisung ein Assign, deshalb keine Probleme an der Stelle)
tmpBMP := Objekt.GetRendering;
try imgBild.Picture.Bitmap := tmpBMP; finally tmpBMP.Destroy; end; Gelößt sah es dann so aus:
Delphi-Quellcode:
Variante 3 würde daraus folgendes machen:
imgBild.Picture.Bitmap := Objekt.GetRendering;
Delphi-Quellcode:
Das ist kürzer, unmissverständlich, erzeugt keine unnötige Bitmap und man bekommt das Objekt das etwas tut an den Anfang der Code-Zeile. Klarer Fall :)
Objekt.RenderInto( imgBild.Picture.Bitmap );
|
Re: Wo gebt ihr Objekte frei?
Zitat:
Und nochmal allgemein zu FreeAndNil (also nicht @Christian). Ich halte FreeAndNil für eine Unsitte. Ich arbeite schon so lange mit Objekten, aber es ist mir noch nie ... ups, das Objekt ist ja schon freigegeben ... passiert. Fehler können passieren, aber jenseits der Fehler weiß ich immer was mein Objekt macht. Mir ist schon klar, daß man gelegentlich auch abfragt ob ein Objekt Nil ist. Allerdings sind das dann Sondersituationen. In diesem Fall kann man meinetwegen das Objekt nil setzten, damit man an einer anderen Stelle prüfen kann ob es nil ist. In diesem Fall ist es ein Teil der Programmierung, denn Nil ist auch eine Information und wenn man mit dieser Information arbeiten muß oder will, dann nutzt man sie. Dann allerdings bewusst. Aber so oft kommt sowas nicht vor, also wozu das Ganze (beinahe hätte ich "Unsinn" gesagt)? Anscheinend ist es eine Mode, wie vor einigen Jahren der Gummiüberzug für die Fernbedienung. Plötzlich hatte für einen gewissen Zeitraum die gesamte Republik ihre Fernbedienungen mit einem Gummipolster geschützt, für den Fall, daß die Fernbedienung auf den Boden fällt. Plötzlich gab es kein Gummi für die Autoreifen, weil alle ihre Fernbedienungen schützten. Also wozu dieses Nil bei der Freigabe von Objekten? Wer nutzt ein Objekt das bereits freigegeben worden ist? Wer FreeAndNil nutzt, der mag auch die Methode zwei, denn da muß man wirklich wissen ob ein Objekt bereits freigegeben worden ist und auf das kann man mit Nil hinweisen. Ansonsten überlege ich wirklich wo man das in der Allgemeinprogrammierung anwenden kann. In besonderen Situationen meinetwegen, aber sonst? |
Re: Wo gebt ihr Objekte frei?
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:48 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