smart shared_ptr example c++ c++11 smart-pointers auto-ptr unique-ptr

c++ - shared_ptr - std:: auto_ptr a std:: unique_ptr



smart pointers c++ (4)

Con la llegada del nuevo estándar (y las partes ya están disponibles en algunos compiladores), se supone que el nuevo tipo std::unique_ptr es un reemplazo para std::auto_ptr .

¿Su uso se superpone exactamente (por lo que puedo hacer un descubrimiento / reemplazo global en mi código (no es que lo haga, pero si lo hiciera)) o debería ser consciente de algunas diferencias que no son evidentes al leer la documentación?

También si es un reemplazo directo (por qué darle un nuevo nombre) en lugar de simplemente mejorar el std::auto_ptr .


AFAIK, unique_ptr no es un reemplazo directo. El principal defecto que corrige es la transferencia implícita de propiedad.

std::auto_ptr<int> a(new int(10)), b; b = a; //implicitly transfers ownership std::unique_ptr<int> a(new int(10)), b; b = std::move(a); //ownership must be transferred explicitly

Por otro lado, unique_ptr tendrá capacidades completamente nuevas: se pueden almacenar en contenedores.


Herb Sutter tiene una buena explicación sobre GotW # 89 :

¿Cuál es el problema con auto_ptr? auto_ptr se caracteriza más caritativamente como un valiente intento de crear un unique_ptr antes de que C ++ tenga una semántica de movimiento. auto_ptr ahora está en desuso, y no debería usarse en un código nuevo.

Si tiene auto_ptr en una base de código existente, cuando tenga la oportunidad intente realizar una búsqueda y reemplazo global de auto_ptr a unique_ptr; la gran mayoría de los usos funcionará de la misma manera, y podría exponer (como un error de tiempo de compilación) o arreglar (silenciosamente) un error o dos que no sabías que tenías.

En otras palabras, aunque una búsqueda y reemplazo global puede "romper" temporalmente su código, debe hacerlo de todos modos: puede tomar algún tiempo corregir los errores de compilación, pero le ahorrará muchos más problemas a largo plazo.


No puede hacer un descubrimiento / reemplazo global porque puede copiar un auto_ptr (con consecuencias conocidas), pero un unique_ptr solo se puede mover. Cualquier cosa que se vea

std::auto_ptr<int> p(new int); std::auto_ptr<int> p2 = p;

tendrá que ser al menos así

std::unique_ptr<int> p(new int); std::unique_ptr<int> p2 = std::move(p);

En cuanto a otras diferencias, unique_ptr puede manejar matrices correctamente (llamará a delete[] , mientras que auto_ptr intentará llamar a delete .


std::auto_ptr y std::unique_ptr son incompatibles de alguna manera y un reemplazo en otros. Entonces, no encontrar / reemplazar no es lo suficientemente bueno. Sin embargo, después de encontrar / reemplazar el trabajo a través de los errores de compilación debería arreglar todo, excepto casos de esquina extraños. La mayoría de los errores de compilación requerirán agregar un std::move .

  • Variable de alcance de función:
    100% compatible, siempre que no lo transfiera por valor a otra función.
  • Tipo de devolución:
    no es 100% compatible, pero 99% compatible no parece estar mal.
  • Parámetro de función por valor:
    100% compatible con una advertencia, unique_ptr s se debe pasar a través de una llamada std::move . Este es simple ya que el compilador se quejará si no lo hace bien.
  • Parámetro de función por referencia:
    100% compatible.
  • Variable miembro de la clase:
    Este es complicado. std::auto_ptr s la semántica de copia es malvada. Si la clase no permite la copia, std::unique_ptr es un reemplazo. Sin embargo, si intentas darle a la clase una semántica de copia razonable, deberás cambiar el código de manejo std::auto_ptr . Esto es simple ya que el compilador se quejará si no lo hace bien. Si permitiste copiar una clase con un miembro std::auto_ptr sin ningún código especial, entonces la culpa es de ti y buena suerte.

En resumen, std::unique_ptr es un std::auto_ptr ininterrumpido. No permite comportamientos de tiempo de compilación que a menudo son errores al usar std::auto_ptr . Por lo tanto, si utilizó std::auto_ptr con el cuidado que necesitaba, cambiar a std::unique_ptr debería ser simple. Si std::auto_ptr el comportamiento impar de std::auto_ptr , entonces necesitas refactorizar tu código de todos modos.