smart - c++ shared pointer
¿Por qué es incorrecto usar std:: auto_ptr<> con contenedores estándar? (6)
¿Por qué es incorrecto usar std::auto_ptr<>
con contenedores estándar?
Dos artículos super excelentes sobre el tema:
El estándar de C ++ dice que un elemento STL debe ser "copiable construible" y "asignable". En otras palabras, un elemento debe poder asignarse o copiarse y los dos elementos son lógicamente independientes. std::auto_ptr
no cumple este requisito.
Tomemos por ejemplo este código:
class X
{
};
std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);
std::auto_ptr<X> pX = vecX[0]; // vecX[0] is assigned NULL.
Para superar esta limitación, debe usar los punteros inteligentes std::unique_ptr
, std::shared_ptr
o std::weak_ptr
o los equivalentes de boost si no tiene C ++ 11. Aquí está la documentación de la biblioteca de impulso para estos punteros inteligentes.
La semántica de copia de auto_ptr
no es compatible con los contenedores.
Específicamente, copiar un auto_ptr
a otro no crea dos objetos iguales ya que uno ha perdido su propiedad del puntero.
Más específicamente, copiar un auto_ptr
hace que una de las copias suelte el puntero. Cuál de estos restos en el contenedor no está definido. Por lo tanto, puede perder aleatoriamente el acceso a los punteros si almacena auto_ptrs
en los contenedores.
Los contenedores STL almacenan copias de los artículos contenidos. Cuando se copia un auto_ptr, establece el ptr antiguo en nulo. Muchos métodos de contenedor están rotos por este comportamiento.
Los contenedores STL deben poder copiar los artículos que almacena en ellos, y están diseñados para esperar que el original y la copia sean equivalentes. Los objetos de puntero automático tienen un contrato completamente diferente, por lo que la copia crea una transferencia de propiedad. Esto significa que los contenedores de auto_ptr exhibirán un comportamiento extraño, dependiendo del uso.
Hay una descripción detallada de lo que puede salir mal en el artículo 8 de Effective STL (Scott Meyers) y también una descripción no tan detallada en el artículo 13 de Effective C ++ (Scott Meyers).
La norma C ++ 03 (ISO-IEC 14882-2003) dice en el párrafo 3 de la cláusula 20.4.5:
[...] [ Nota: [...] auto_ptr no cumple con los requisitos CopyConstructible y Assignable para los elementos del contenedor de la Biblioteca estándar y, por lo tanto, crear una instancia de un contenedor de la Biblioteca estándar con un auto_ptr produce un comportamiento indefinido. - nota final ]
La norma C ++ 11 (ISO-IEC 14882-2011) dice en el apéndice D.10.1 párrafo 3:
[...] Nota: [...] Las instancias de auto_ptr cumplen con los requisitos de MoveConstructible y MoveAssignable, pero no cumplen con los requisitos de CopyConstructible y CopyAssignable. - nota final]
La norma C ++ 14 (ISO-IEC 14882-2014) dice en el apéndice C.4.2 Anexo D: características de compatibilidad:
Cambio : las plantillas de clase auto_ptr, unary_function y binary_function, las plantillas de función random_shuffle y las plantillas de función (y sus tipos de devolución) ptr_fun, mem_fun, mem_fun_ref, bind1st y bind2nd no están definidas.
Fundamento : Reemplazado por nuevas características.
Efecto en la característica original : el código válido de C ++ 2014 que utiliza estas plantillas de clase y las plantillas de función puede no compilarse en esta Norma Internacional.