Me pregunto qué méritos posibles tiene la copia en escritura. Naturalmente, no espero opiniones personales, sino escenarios prácticos del mundo real en los que pueda ser técnica y prácticamente beneficiosa de una manera tangible. Y por tangible me refiero a algo más que ahorrarte la escritura de un &
personaje.
Para aclarar, esta pregunta es en el contexto de los tipos de datos, donde la construcción de asignación o copia crea una copia superficial implícita, pero las modificaciones a la misma crean una copia profunda implícita y le aplican los cambios en lugar del objeto original.
La razón por la que pregunto es que no parece encontrar ningún mérito de tener COW como un comportamiento implícito predeterminado. Utilizo Qt, que tiene COW implementado para muchos de los tipos de datos, prácticamente todos los cuales tienen un almacenamiento subyacente asignado dinámicamente. Pero, ¿cómo beneficia realmente al usuario?
Un ejemplo:
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"
¿Qué ganamos usando COW en este ejemplo?
Si todo lo que pretendemos hacer es usar operaciones constantes, s1
es redundante, también podríamos usarlo s
.
Si tenemos la intención de cambiar el valor, entonces COW solo retrasa la copia del recurso hasta la primera operación no constante, al costo (aunque mínimo) de incrementar el recuento de referencias para el uso compartido implícito y la separación del almacenamiento compartido. Parece que todos los gastos generales involucrados en COW no tienen sentido.
No es muy diferente en el contexto del paso de parámetros: si no tiene la intención de modificar el valor, pase como referencia constante, si desea modificar, haga una copia profunda implícita si no desea modificar el objeto original, o pase por referencia si desea modificarlo. Una vez más, COW parece una sobrecarga innecesaria que no logra nada, y solo agrega una limitación de que no puede modificar el valor original incluso si lo desea, ya que cualquier cambio se separará del objeto original.
Por lo tanto, dependiendo de si sabe acerca de COW o si no lo tiene en cuenta, puede generar un código con intenciones oscuras y gastos generales innecesarios, o un comportamiento completamente confuso que no coincide con las expectativas y lo deja rascándose la cabeza.
Para mí, parece que hay soluciones más eficientes y más legibles, ya sea que desee evitar una copia profunda innecesaria o si tiene la intención de hacer una. Entonces, ¿dónde está el beneficio práctico de COW? Supongo que debe haber algún beneficio ya que se usa en un marco tan popular y poderoso.
Además, por lo que he leído, COW ahora está explícitamente prohibido en la biblioteca estándar de C ++. No sé si las estafas que veo en él tienen algo que ver con eso, pero de cualquier manera, debe haber una razón para esto.
[]
operador. Entonces, COW permite un mal diseño, eso no parece un gran beneficio :) El punto en el último párrafo parece válido, pero yo mismo no soy un gran admirador del comportamiento implícito: las personas tienden a darlo por sentado, y luego tienen es difícil descubrir por qué el código no funciona como se esperaba, y seguir preguntándose hasta que descubran qué oculta detrás del comportamiento implícito.