Moin Nerd,
Zitat von
NerdIII:
'Objekte da freigeben wo sie erzeugt werden.' heißt es so schön.
heisst es wo so schön?
Ich finde diese Aussage sehr unverständlich. Da gefällt mir die von Thomas doch erheblich besser.
Um die abstrakte Aussage mit der gleichen Ebene von Erzeugen und Löschen mal zu konkretisieren:
Wenn ich ein Objekt im initialization-Abschnitt erzeuge, wird es im finalization-Abschnitt wieder freigegeben
Wenn ich ein Objekt in einem Konstruktor erzeuge, wird es im zugehörigen Destruktor wieder zerstört.
Wenn ich ein Objekt in einer Prozedur/Methode erzeuge, wird es auch dort wieder freigegeben.
Bei letztgenanntem Falle sehe ich allerdings auch Ausnahmen:
Wenn ein Objekt erzeugt wird, dass dann in einer Liste vorgehalten wird (z.B. eine TObjectList) werden sie, natürlich, nicht gleich in der Prozedur/Methode wieder freigegeben (wobei diese Liste dann ja als Owner einer Komponente fungiert).
Die zweite Ausnahme die ich hier sehe, ist das Erzeugen einer Komponente, wenn hier im Constructor ein Owner angegeben wird, der dann ja für die Freigabe verantwortlich ist.
Sollte ich so ein global erzeugtes Objekt zwischendurch mal wieder leeren müssen, geschieht dies durch eine entsprechende Methode, und nicht durch Free und erneutes Create. Beispielsweise habe ich da ein Projekt, in dem ich ein paar StringListen immer wieder benötige. Die werden im OnCreate des Formulares erzeugt, im OnDestroy wieder freigegeben, und zwischendurch mit Clear immer mal wieder geleert.
Um das auf Deine drei Möglichkeiten anzuwenden:
Zu 1.:
Kommt überhaupt nicht in Frage, da hier viel zu leicht die Übersicht verloren gehen kann, und man sich leicht Speicherlöcher einhandelt. Stell Dir vor, dass passiert Dir in einem Dienst, der auf einem Server läuft...
Zu 2.:
Schon etwas besser als 1. aber wenn Du die angesprochende Kopiermethode verwendest muss sich doch wieder eine andere Stelle darum kümmern aufzuräumen. Ausserdem kann es Dir hier passieren, dass ein Programmteil noch mit einem Objekt arbeiten will, dass bereits durch den Aufruf der gleichen Methode in einem anderen Programmteil zerstört wurde. Aus diesem Grunde halte ich diese Möglichkeit für recht unübersichtlich.
Zu 3.:
Meiner Ansicht nach die sinnvollste Variante. Deinen Negativpunkt kann ich allerdings nicht nachvollziehen, eher im Gegenteil. Man sieht gleich woran man ist.
Ich würde diese Vorgehensweise übrigens nicht auf Objekte einschränken, sondern auf alle Resourcen anwenden die angefordert werden, z.B. auch Handles.
Es gibt übrigens sogar
API-Funktionen, die Resourcen selber reservieren (z.B. viele NetXXX-Funktionen), und für die es explizit Funktionen gibt, mit denen diese vom Aufrufer wieder freizugeben sind.
Das dient dort übrigens nur dem Komfort sich nicht selber um erforderliche Buffergrösse kümmern zu müssen, wie bei so manch anderer
API-Funktion.