what smart pointer c++ stl raii auto-ptr c++-faq

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?



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.