Mi chiedo quali sono i possibili vantaggi che ha il copy-on-write? Naturalmente, non mi aspetto opinioni personali, ma scenari pratici del mondo reale in cui può essere tecnicamente e praticamente utile in modo tangibile. E per tangibile intendo qualcosa di più che salvarti la digitazione di un carattere &
.
Per chiarire, questa domanda è nel contesto dei tipi di dati, in cui l'assegnazione o la costruzione di copia crea una copia implicita superficiale, ma le modifiche apportate creano una copia implicita e applica le modifiche ad esso anziché l'oggetto originale.
La ragione per cui la sto chiedendo è che non trovo alcun merito di avere COW come comportamento implicito predefinito. Io uso Qt, che ha implementato COW per molti dei tipi di dati, praticamente tutti che hanno una memoria allocata dinamicamente sottostante. Ma in che modo può davvero giovare all'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 è usare le operazioni const, s1
è ridondante, potrebbe anche usare s
.
Se intendiamo modificare il valore, allora COW ritarda la copia della risorsa solo fino alla prima operazione non const, al costo (anche se minimo) di incrementare il conteggio ref per la condivisione implicita e la disconnessione dalla memoria condivisa. Sembra che tutto il sovraccarico di COW sia inutile.
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 effettua una copia implicita se non si vuoi modificare l'oggetto originale o passare per riferimento se desideri modificarlo. Ancora una volta COW sembra un sovraccarico inutile che non raggiunge nulla e aggiunge solo una limitazione che non è possibile modificare il valore originale anche se lo si desidera, poiché qualsiasi modifica si scollegherà dall'oggetto originale.
Quindi, a seconda che tu sappia di COW o di esserne ignaro, potrebbe comportare un codice con intenzioni oscure e overhead inutili, o un comportamento completamente confuso che non corrisponde alle aspettative e ti lascia grattando la testa.
Per me sembra che ci siano soluzioni più efficienti e più leggibili se si vuole evitare una copia profonda non necessaria o se si intende crearne una. Allora, dov'è il vantaggio pratico di COW? Presumo che ci deve essere qualche vantaggio in quanto utilizzato in un framework così popolare e potente.
Inoltre, da quello che ho letto, COW è ora esplicitamente proibito nella libreria standard C ++. Non so se il contro che vedo in esso abbia qualcosa a che fare con esso, ma in ogni caso, ci deve essere una ragione per questo.