Il metodo Free
non genera esplicitamente un'eccezione, ma chiama il distruttore virtuale Destroy
che sicuramente potrebbe generare un'eccezione.
Quindi, se si vuole essere sicuri che tutti gli oggetti vengono distrutti, anche se uno dei distruttori solleva un'eccezione si finisce con codice come questo:
a := TMyObject.Create;
try
b := TMyObject.Create;
try
...
finally
b.Free;
end;
finally
a.Free;
end;
Detto questo, dovrebbe essere un principio di progettazione che non si generano eccezioni in un distruttore. Quindi, a mio avviso, è perfettamente ragionevole considerare il punto di vista secondo cui se viene sollevata un'eccezione in distruttore, il tuo programma viene praticamente bloccato. La perdita di oggetti a quel punto non è qualcosa di cui preoccuparsi. Se il tuo distruttore ha sollevato un'eccezione, probabilmente stai già perdendo perché quel distruttore non è stato eseguito fino al completamento.
Quindi, a mio parere, può essere perfettamente ragionevole raggruppare alcune chiamate a Free
e, naturalmente, si evita di nidificazione try
/finally
che è qualcosa vale la pena lottare per.
Se si desidera solo un try
/finally
poi ricordare a scrivere il codice come questo:
a := nil;
b := nil;
try
a := TMyObject.Create;
b := TMyObject.Create;
...
finally
b.Free;
a.Free;
end;
Nella mia base di codice Ho alcuni metodi di supporto che rendono questo più pulito.Poi il codice può assomigliare a questo:
InitialiseNil(a, b);
try
a := TMyObject.Create;
b := TMyObject.Create;
...
finally
FreeAndNil(b, a);
end;
ho dato il mio FreeAndNil
lo stesso nome della funzione in SysUtils
che a prima vista può sembrare strano, ma è sicuro e benigna per farlo. Naturalmente questi aiutanti entrano in gioco quando hai anche più di due oggetti.
Perché il downvotore di interesse? È una domanda chiara, non c'è ambiguità e volevo sinceramente conoscere la risposta. * Shrug * –
Penso che tu abbia accettato una risposta qui troppo veloce. – NGLN
@NGLN: Accetto davvero (scusate TOndrej), penso che la risposta di David sia molto meglio. –