Buonasera,
Nel caso io avessi una funzione che restituisce un oggetto come ad esempio:
Function Elenco:TstringList;
begin
Result:=TStringList.Create;
Result.Add('Prova');
// e via dicendo...
// fà altre cose...
end;
Si può chiamare la funzione con un assegnamento del tipo:
try
MyLista:=Elenco;
Finally
MyLista.Free
end;
Ma nulla vieta di chiamare anche semplicemente
In questo caso però non è stato chiamato il distruttore e quindi si ha perdita di memoria!
La domanda è:
C'è la possibilità dall'interno della funzione stessa (alla fine) di verificare se è stata assegnata e nel caso contrario procedere alla liberazione di memoria con ad esempio una cosa del tipo:
If not assigned(Result) then
Result.free;
Grazie a tutti!
Ma nulla vieta di chiamare anche semplicemente
In questo caso però non è stato chiamato il distruttore e quindi si ha perdita di memoria!
In effetti in questi casi è meglio dare dei nomi più significativi a queste funzioni.
Se istanziano un oggetto in memoria e non si occupano di liberarlo, un nome più adatto potrebbe essere:
Non cambia assolutamente nulla chiaramente, ma già ti da un indizio sul fatto che devi verificare chi libererà la cosa creata.
Una alternativa è evitare che una funzione istanzi risorse se poi non è possibile essere sicuri che all'uscita queste risorse saranno liberate.
L'approccio è quello di lasciare che sia il chiamante a preoccuparsi della vita degli oggetti e fare una procedura tipo:
procedure PopolaElenco(sl: TStrings);
begin
sl.Clear;
sl.Add('...');
sl.Add('...');
sl.Add('...');
end;
in questo modo sarà il chiamante a dover fornire un oggetto esistente che verrà poi popolato.
Edit:
Il messaggio di fondo è che è meglio associare un verbo al sostantivo quando si da un nome alle procedure/funzioni.
Personalmente preferisco di gran lunga l'approccio 'PopolaElenco' in quanto sgancia totalmente la funzione dal contesto in cui verrà utilizzata.