Mi chiedo quali possibili meriti ha il copy-on-write? Naturalmente, non mi aspetto opinioni personali, ma scenari pratici del mondo reale in cui può essere tecnicamente e praticamente vantaggioso in modo tangibile. E per tangibile intendo qualcosa di più che salvarti la digitazione di un &
personaggio.
Per chiarire, questa domanda è nel contesto dei tipi di dati, in cui l'assegnazione o la costruzione della copia crea una copia superficiale implicita, ma le modifiche ad essa creano una copia profonda implicita e applicano le modifiche ad essa anziché l'oggetto originale.
Il motivo per cui lo sto chiedendo è che non trovo alcun merito di avere COW come comportamento implicito predefinito. Uso Qt, che ha implementato COW per molti tipi di dati, praticamente tutti quelli che hanno una memoria sottostante allocata dinamicamente. Ma come va a beneficio dell'utente?
Un esempio:
QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource
qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
// s is still "some text"
Cosa vinciamo usando COW in questo esempio?
Se tutto ciò che intendiamo fare è utilizzare le operazioni const, s1
è ridondante, potrebbe anche essere utile s
.
Se intendiamo modificare il valore, COW ritarda solo la copia della risorsa fino alla prima operazione non const, al costo (sebbene minimo) di aumentare il conteggio di riferimento per la condivisione implicita e il distacco dalla memoria condivisa. Sembra che tutte le spese generali coinvolte in COW siano inutili.
Non è molto diverso nel contesto del passaggio dei parametri: se non si intende modificare il valore, passare come riferimento const, se si desidera modificare, si può fare una copia profonda implicita se non si desidera modificare l'oggetto originale o passare per riferimento se si desidera modificarlo. Ancora una volta COW sembra inutile sovraccarico che non raggiunge nulla e aggiunge solo una limitazione che non è possibile modificare il valore originale anche se si desidera, poiché qualsiasi modifica si staccherà dall'oggetto originale.
Quindi, a seconda che tu sia a conoscenza di COW o che tu ne sia ignaro, potrebbe risultare in un codice con intenti oscuri e inutili spese generali, o un comportamento completamente confuso che non corrisponde alle aspettative e ti lascia grattarti la testa.
A me sembra che ci siano soluzioni più efficienti e più leggibili se si desidera evitare una copia profonda non necessaria o se si intende realizzarne una. Allora, qual è il vantaggio pratico di COW? Presumo che ci debba essere qualche vantaggio poiché utilizzato in un framework così popolare e potente.
Inoltre, da quello che ho letto, COW è ora esplicitamente vietato nella libreria standard C ++. Non so se le truffe che vedo in essa hanno qualcosa a che fare con esso, ma in entrambi i casi, ci deve essere una ragione per questo.
[]
operatore. Quindi COW consente una cattiva progettazione - che non sembra un grande vantaggio :) Il punto nell'ultimo paragrafo sembra valido, ma io stesso non sono un grande fan del comportamento implicito - le persone tendono a darlo per scontato, e quindi hanno è difficile capire perché il codice non funziona come previsto e continuare a chiedersi fino a quando non riescono a controllare cosa è nascosto dietro il comportamento implicito.