Escuché que auto_ptr
está siendo obsoleto en C ++ 11. ¿Cuál es la razón para esto?
También me gustaría saber la diferencia entre auto_ptr
y shared_ptr
.
c++
c++11
smart-pointers
auto-ptr
brett
fuente
fuente
Respuestas:
El reemplazo directo de
auto_ptr
(o lo más parecido a uno de todos modos) esunique_ptr
. En lo que respecta al "problema", es bastante simple:auto_ptr
transfiere la propiedad cuando se asigna.unique_ptr
también transfiere la propiedad, pero gracias a la codificación de la semántica de movimientos y la magia de las referencias rvalue, puede hacerlo de forma considerablemente más natural. También "encaja" con el resto de la biblioteca estándar considerablemente mejor (aunque, para ser justos, algo de eso se debe a que el resto de la biblioteca cambió para adaptarse a la semántica de movimiento en lugar de requerir siempre copia).El cambio de nombre también es (en mi opinión) bienvenido: en
auto_ptr
realidad no le dice mucho sobre lo que intenta automatizar, mientras queunique_ptr
es una descripción bastante razonable (aunque concisa) de lo que se proporciona.fuente
auto_ptr
nombre: auto sugiere automático como variable automática, y se refiere a una cosa queauto_ptr
hace: destruir el recurso administrado en su destructor (cuando sale del alcance).auto_ptr
: open-std.org/jtc1/sc22/wg21/docs/papers/2005/…std::sort
no tiene especialización enunique_ptr
. En cambio, se volvió a especificar para no copiar nunca. Así queauto_ptr
en realidad hace el trabajo con el modernosort
. Pero el C ++ 98/03sort
es solo un algoritmo de ejemplo aquí: cualquier algoritmo genérico (proporcionado por el estándar o escrito por el usuario) que asume que la sintaxis de copia tiene semántica de copia probablemente tendrá un error de tiempo de ejecución si se usa conauto_ptr
, porqueauto_ptr
se mueve silenciosamente con sintaxis de copia . El problema es mucho más grande que solosort
.Encontré excelentes respuestas existentes, pero desde el punto de vista de los punteros. En mi opinión, una respuesta ideal debe tener la respuesta de perspectiva del usuario / programador.
Primero lo primero (como lo señaló Jerry Coffin en su respuesta)
shared_ptr: Si le preocupa la liberación de recursos / memoria Y si tiene más de una función que podría estar usando el objeto AT-DIFFERENT veces, vaya con shared_ptr.
Por DIFFERENT-Times, piense en una situación en la que el objeto-ptr se almacena en múltiples estructuras de datos y luego se accede a él. Varios hilos, por supuesto, es otro ejemplo.
unique_ptr: Si lo único que le preocupa es liberar memoria y el acceso al objeto es SECUENCIAL, elija unique_ptr.
Por SECUENCIAL, quiero decir, en cualquier punto se accederá al objeto desde un contexto. Por ejemplo, un objeto que fue creado y utilizado inmediatamente después de la creación por el creador. Después de la creación, el objeto se almacena en la PRIMERA estructura de datos. Luego, el objeto se destruye después de la UNA estructura de datos o se mueve a la SEGUNDA estructura de datos.
Desde esta línea, me referiré a _ptr compartido / único como punteros inteligentes. (auto_ptr también es un puntero inteligente, PERO debido a fallas en su diseño, por lo que están en desuso, y que creo que señalaré en las siguientes líneas, no deben agruparse con el puntero inteligente).
Desde el enlace: http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
Tipo de asignaciones admitidas por unqiue_ptr
De: http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
Tipo de asignaciones admitidas por auto_ptr
Ahora, llegando a la razón por la que la asignación de copia en sí misma no le gustó tanto, tengo esta teoría:
El comportamiento no deseado es realmente desagradable y, por lo tanto, el desagrado por auto_ptr.
(Para el 3.1415926536% de los programadores que intencionalmente quieren transferir la propiedad, C ++ 11 les dio std :: move (), lo que dejó en claro su intención para todos los pasantes que leerán y mantendrán el código).
fuente
auto_ptr
valores que apunten al mismo objeto (dado que no dan propiedad compartida, el primero en morir dejará al otro con una herencia letal; esto también es cierto para elunique_ptr
uso), ¿puede sugerir lo que se pretendía en los restantes 96.8584073465% de todo el uso?*a=*b;
aquí solo el valor de b se copia en a. Espero que la propiedad de a y b siga perteneciendo a las mismas personas. Mencionaste que la propiedad será transferida. ¿Cómo sera?auto_ptr
objeto en sí. La asignación a / desde su valor señalado no tiene efecto ni relevancia para la propiedad. Espero que no se sigue usandoauto_ptr
?shared_ptr
se puede almacenar dentro de contenedores.auto_ptr
hipocresía.Por cierto,
unique_ptr
es realmente elauto_ptr
reemplazo directo , combina las mejores características de ambosstd::auto_ptr
yboost::scoped_ptr
.fuente
Otra versión más para explicar la diferencia ...
Funcionalmente, C ++ 11
std::unique_ptr
es el "fijo"std::auto_ptr
: ambos son adecuados cuando, en cualquier momento durante la ejecución, debería haber un único propietario de puntero inteligente para un objeto apuntado.La diferencia crucial está en la construcción de copias o la asignación de otro puntero inteligente que no expira, que se muestra en las
=>
líneas siguientes:Arriba,
ap3
silenciosamente "roba" la propiedad de*ap
, dejándoloap
configurado en anullptr
, y el problema es que puede suceder con demasiada facilidad, sin que el programador haya pensado en su seguridad.Por ejemplo, si un
class
/struct
tiene unstd::auto_ptr
miembro, al hacer una copia de una instancia aparecerárelease
el puntero de la instancia que se está copiando: esa es una semántica extraña y peligrosamente confusa, ya que normalmente copiar algo no lo modifica. Es fácil para el autor de la clase / estructura pasar por alto la liberación del puntero cuando razona sobre invariantes y estados y, en consecuencia, intenta accidentalmente desreferenciar el puntero inteligente mientras es nulo, o simplemente no tiene el acceso / propiedad esperado de los datos apuntados.fuente
auto_ptr no se puede usar en contenedores STL porque tiene un constructor de copia que no cumple con los requisitos del contenedor CopyConstructible . unique_ptr no implementa un constructor de copia, por lo que los contenedores usan métodos alternativos. unique_ptr se puede usar en contenedores y es más rápido para los algoritmos estándar que shared_ptr.
fuente