Considera la seguente implementazione di elenchi collegati singolarmente:
struct node {
std::unique_ptr<node> next;
ComplicatedDestructorClass data;
}
Ora, supponiamo che io smetta di usare qualche istanza di std::unique_ptr<node> head
che poi esce dall'ambito, provocando la chiamata del suo distruttore.
Questo farà esplodere il mio stack per elenchi sufficientemente grandi? È giusto presumere che il compilatore esegua un'ottimizzazione piuttosto complicata (distruttore in-linea unique_ptr
in node
, quindi usi ricorsione di coda), che diventa molto più difficile se faccio quanto segue (dal momento che data
il distruttore avrebbe offuscato next
, rendendo difficile per il compilatore notare il potenziale riordino e l'opportunità di chiamare tail):
struct node {
std::shared_ptr<node> next;
ComplicatedDestructorClass data;
}
Se data
ha in qualche modo un puntatore al suo node
, allora potrebbe anche essere impossibile per la ricorsione in coda (anche se ovviamente dovremmo sforzarci di evitare tali violazioni dell'incapsulamento).
In generale, come si dovrebbe distruggere questa lista altrimenti? Non possiamo attraversare l'elenco ed eliminare il nodo "corrente" perché il puntatore condiviso non ha un release
! L'unico modo è con un deleter personalizzato, che è davvero maleodorante per me.