Sono contento che tu abbia postato questa domanda come una domanda. :)
Stavo cercando di dire che i distruttori e finally
sono concettualmente diversi:
- I distruttori servono per il rilascio di risorse ( dati )
-
finally
serve per tornare al chiamante ( controllo )
Considera, per esempio, questo ipotetico pseudo-codice:
try {
bar();
} finally {
logfile.print("bar has exited...");
}
finally
qui sta risolvendo interamente un problema di controllo e non un problema di gestione delle risorse.
Non avrebbe senso farlo in un distruttore per una serie di motivi:
- Nessuna cosa viene "acquisita" o "creata"
- La mancata stampa sul file di log non causerà perdite di risorse, danneggiamento dei dati, ecc. (supponendo che il file di registro qui non venga reimmesso nel programma altrove)
- È legittimo che
logfile.print
fallisca, mentre destruction (concettualmente) non può fallire
Ecco un altro esempio, questa volta come in Javascript:
var mo_document = document, mo;
function observe(mutations) {
mo.disconnect(); // stop observing changes to prevent re-entrance
try {
/* modify stuff */
} finally {
mo.observe(mo_document); // continue observing (conceptually, this can fail)
}
}
mo = new MutationObserver(observe);
return observe();
Nell'esempio precedente, ancora una volta, non ci sono risorse da rilasciare.
Infatti, il blocco finally
è acquisire risorse internamente per raggiungere il suo obiettivo, che potrebbe potenzialmente fallire. Quindi, non ha senso usare un distruttore (se Javascript ne ha uno).
D'altra parte, in questo esempio:
b = get_data();
try {
a.write(b);
} finally {
free(b);
}
finally
sta distruggendo una risorsa, b
. È un problema di dati. Il problema non riguarda il ritorno pulito del controllo al chiamante, ma piuttosto l'eliminazione delle perdite di risorse.
Il fallimento non è un'opzione e dovrebbe (concettualmente) non accadere mai.
Ogni rilascio di b
è necessariamente associato a un'acquisizione e ha senso utilizzare RAII.
In altre parole, solo perché è possibile utilizzare sia per simulare che non significa che entrambi sono lo stesso problema o che entrambi sono soluzioni appropriate per entrambi i problemi.