c++ stl boost shared-ptr auto-ptr

c++ - ¿Cuándo usarías un std:: auto_ptr en lugar de boost:: shared_ptr?



stl shared-ptr (3)

Nos hemos movido a usar boost::shared_ptr en todo nuestro código, sin embargo, todavía tenemos algunos casos aislados en los que usamos std::auto_ptr , incluidas las clases singleton:

template < typename TYPE > class SharedSingleton { public: static TYPE& Instance() { if (_ptrInstance.get() == NULL) _ptrInstance.reset(new TYPE); return *_ptrInstance; } protected: SharedSingleton() {}; private: static std::auto_ptr < TYPE > _ptrInstance; };

Me han dicho que hay una muy buena razón por la que esto no se ha hecho un shared_ptr , pero por mi vida no puedo entender por qué. Sé que auto_ptr eventualmente se marcará como depreciado en el siguiente estándar, así que me gustaría saber qué / cómo puedo reemplazar esta implementación .

Además, ¿existen otras razones por las que consideraría usar un auto_ptr lugar de shared_ptr ? ¿Y ve algún problema para pasar a shared_ptr en el futuro?

Editar:

  1. Entonces, en respuesta a "¿puedo reemplazar de forma segura a auto_ptr con shared_ptr en el código anterior", la respuesta es sí? Sin embargo, recibiré un pequeño impacto de rendimiento.
  2. Cuando auto_ptr finalmente se marca como depreciado y nos movemos a std::shared_ptr , tendremos que probar exhaustivamente nuestro código para asegurarnos de que cumplimos con la semántica de propiedad diferente.

Otros han respondido por qué este código utiliza un auto_ptr lugar de un shared_ptr . Para abordar sus otras preguntas:

¿Qué / cómo puedo reemplazar esta implementación?

Use boost::scoped_ptr o unique_ptr (disponible tanto en Boost como en el nuevo estándar de C ++). Tanto scoped_ptr como unique_ptr proporcionan una propiedad estricta (y no tienen gastos generales de conteo de referencias), y evitan la sorprendente semántica de eliminación en copia de auto_ptr .

Además, ¿existen otras razones por las que consideraría usar un auto_ptr lugar de shared_ptr ? ¿Y ve algún problema para pasar a shared_ptr en el futuro?

Personalmente, no usaría un auto_ptr . Eliminar-en-copiar es demasiado no intuitivo. Herb Sutter parece estar de acuerdo . Cambiar a scoped_ptr , unique_ptr , o shared_ptr debería ofrecer problemas. Específicamente, shared_ptr debe ser un reemplazo shared_ptr si no le importa la sobrecarga de conteo de referencia. scoped_ptr es un reemplazo scoped_ptr si no está usando las capacidades de transferencia de propiedad de auto_ptr . Si está usando la transferencia de propiedad, unique_ptr es casi un reemplazo unique_ptr , excepto que en su lugar debe llamar explícitamente a move para transferir la propiedad. Vea here para un ejemplo.


auto_ptr es el único tipo de puntero inteligente que uso. Lo uso porque no uso Boost, y porque generalmente prefiero que mis clases orientadas a negocios / aplicaciones definan explícitamente la orden y la semántica de eliminación, en lugar de depender de colecciones de punteros inteligentes o individuales.


auto_ptr y shared_ptr resuelven problemas completamente diferentes. Uno no reemplaza al otro.

auto_ptr es una envoltura delgada alrededor de los punteros para implementar la semántica RAII , de modo que los recursos siempre se liberan, incluso cuando se enfrentan a excepciones. auto_ptr no realiza ningún recuento de referencias ni nada similar, no hace que los punteros múltiples apunten al mismo objeto al crear copias. De hecho, es muy diferente. auto_ptr es una de las pocas clases en las que el operador de asignación modifica el objeto de origen . Considere este enchufe descarado de la página wikipedia de auto_ptr :

int *i = new int; auto_ptr<int> x(i); auto_ptr<int> y; y = x; cout << x.get() << endl; // Print NULL cout << y.get() << endl; // Print non-NULL address i

Note como ejecutando

y = x;

modifica no solo y también x.

La plantilla boost::shared_ptr facilita el manejo de múltiples punteros hacia el mismo objeto, y el objeto solo se elimina después de que la última referencia a él se haya salido del alcance. Esta función no es útil en su escenario, que (intenta) implementar un Singleton . En su escenario, siempre hay 0 referencias a 1 referencia al único objeto de la clase, si corresponde.

En esencia, los objetos auto_ptr y shared_ptr tienen una semántica completamente diferente (por eso no puede usar el primero en contenedores, pero hacerlo con el último está bien), y espero que tenga buenas pruebas para detectar las regresiones que introdujo al transportar su código. : -}