C ++ 03
std::auto_ptr
- Quizás uno de los originales sufría del síndrome del primer borrador que solo proporcionaba instalaciones limitadas de recolección de basura. El primer inconveniente es que recurre delete
a la destrucción haciéndolos inaceptables para mantener objetos asignados a la matriz ( new[]
). Toma posesión del puntero, por lo que dos punteros automáticos no deberían contener el mismo objeto. La asignación transferirá la propiedad y restablecerá el puntero automático rvalue a un puntero nulo. Lo que lleva quizás al peor inconveniente; no se pueden usar dentro de contenedores STL debido a la incapacidad antes mencionada de ser copiados. El golpe final para cualquier caso de uso es que están programados para ser obsoletos en el próximo estándar de C ++.
std::auto_ptr_ref
- Este no es un puntero inteligente, en realidad es un detalle de diseño utilizado en conjunto std::auto_ptr
para permitir la copia y asignación en ciertas situaciones. Específicamente, se puede usar para convertir un valor no constante std::auto_ptr
en un valor l utilizando el truco de Colvin-Gibbons, también conocido como un constructor de movimiento para transferir la propiedad.
Por el contrario, tal vez std::auto_ptr
no estaba destinado a ser utilizado como un puntero inteligente de propósito general para la recolección automática de basura. La mayor parte de mi comprensión y suposiciones limitadas se basan en el uso efectivo de auto_ptr de Herb Sutter y lo uso regularmente, aunque no siempre de la manera más optimizada.
C ++ 11
std::unique_ptr
- Este es nuestro amigo que será lo que sustituya std::auto_ptr
será bastante similar, excepto con las mejoras clave para corregir las debilidades de std::auto_ptr
trabajar con matrices, lvalue protección a través de constructor de copia privada, pudiendo utilizarse con contenedores STL y algoritmos, etc. Desde su sobrecarga de rendimiento y la huella de memoria es limitada, este es un candidato ideal para reemplazar, o quizás más acertadamente descrito como propietario, punteros en bruto. Como lo "único" implica que solo hay un propietario del puntero como el anterior std::auto_ptr
.
std::shared_ptr
- Creo que esto se basa en TR1 y se ha boost::shared_ptr
mejorado para incluir alias y aritmética de punteros también. En resumen, envuelve un puntero inteligente contado de referencia alrededor de un objeto asignado dinámicamente. Como "compartido" implica que el puntero puede ser propiedad de más de un puntero compartido cuando la última referencia del último puntero compartido se sale del alcance, entonces el objeto se eliminará adecuadamente. Estos también son seguros para subprocesos y pueden manejar tipos incompletos en la mayoría de los casos. std::make_shared
se puede utilizar para construir de manera eficiente una std::shared_ptr
asignación de un montón utilizando el asignador predeterminado.
std::weak_ptr
- Del mismo modo basado en TR1 y boost::weak_ptr
. Esta es una referencia a un objeto propiedad de ay, por std::shared_ptr
lo tanto, no impedirá la eliminación del objeto si el std::shared_ptr
recuento de referencias cae a cero. Para obtener acceso al puntero sin formato, primero tendrá que acceder std::shared_ptr
llamando llamando, lock
lo que devolverá un espacio vacío std::shared_ptr
si el puntero propiedad ha expirado y ya se ha destruido. Esto es principalmente útil para evitar recuentos de referencias colgantes indefinidos cuando se utilizan múltiples punteros inteligentes.
Aumentar
boost::shared_ptr
- Probablemente el más fácil de usar en los escenarios más variados (STL, PIMPL, RAII, etc.) este es un puntero inteligente contado referenciado compartido. He escuchado algunas quejas sobre el rendimiento y los gastos generales en algunas situaciones, pero debo haberlas ignorado porque no puedo recordar cuál fue el argumento. Aparentemente, era lo suficientemente popular como para convertirse en un objeto C ++ estándar pendiente y no se me ocurren inconvenientes sobre la norma con respecto a los punteros inteligentes.
boost::weak_ptr
- Al igual que la descripción anterior de std::weak_ptr
, basada en esta implementación, esto permite una referencia no propietaria a a boost::shared_ptr
. No es sorprendente que llame lock()
para acceder al puntero compartido "fuerte" y debe verificar para asegurarse de que sea válido, ya que podría haber sido destruido. Solo asegúrate de no almacenar el puntero compartido devuelto y déjalo fuera de alcance tan pronto como hayas terminado con él; de lo contrario, volverás al problema de referencia cíclica donde tus recuentos de referencia se colgarán y los objetos no se destruirán.
boost::scoped_ptr
- Esta es una clase de puntero inteligente simple con poca sobrecarga, probablemente diseñada para una mejor alternativa de rendimiento boost::shared_ptr
cuando sea utilizable. Es comparable std::auto_ptr
especialmente al hecho de que no se puede usar de forma segura como un elemento de un contenedor STL o con múltiples punteros al mismo objeto.
boost::intrusive_ptr
- Nunca he usado esto, pero tengo entendido que está diseñado para usarse al crear sus propias clases compatibles con punteros inteligentes. Debe implementar el recuento de referencias usted mismo, también deberá implementar algunos métodos si desea que su clase sea genérica, además, deberá implementar su propia seguridad de subprocesos. En el lado positivo, esto probablemente le brinda la forma más personalizada de elegir y elegir exactamente cuánto o qué "inteligencia" desea. intrusive_ptr
normalmente es más eficiente que shared_ptr
ya que le permite tener una única asignación de montón por objeto. (gracias Arvid)
boost::shared_array
- Esto es boost::shared_ptr
para matrices. Básicamente new []
, operator[]
y por supuesto delete []
están horneados. Esto se puede usar en contenedores STL y, por lo que sé, hace todo boost:shared_ptr
, aunque no se puede usar boost::weak_ptr
con estos. Sin embargo, también puede usar a boost::shared_ptr<std::vector<>>
para una funcionalidad similar y recuperar la capacidad de usar boost::weak_ptr
para referencias.
boost::scoped_array
- Esto es boost::scoped_ptr
para matrices. Al igual que con boost::shared_array
todas las bondades de matriz necesarias, esta no se puede copiar y, por lo tanto, no se puede usar en contenedores STL. He encontrado casi cualquier lugar en el que desees usar esto que probablemente puedas usar std::vector
. Nunca he determinado cuál es realmente más rápido o tiene menos sobrecarga, pero esta matriz de ámbito parece mucho menos complicada que un vector STL. Cuando desee mantener la asignación en la pila, considere en su boost::array
lugar.
Qt
QPointer
- Introducido en Qt 4.0, este es un puntero inteligente "débil" que solo funciona con QObject
clases derivadas, que en el marco de Qt es casi todo, así que eso no es realmente una limitación. Sin embargo, existen limitaciones, es decir, que no proporciona un puntero "fuerte" y, aunque puede verificar si el objeto subyacente es válido isNull()
, puede encontrar que su objeto se destruye justo después de pasar esa verificación, especialmente en entornos de subprocesos múltiples. La gente considera q esto está en desuso, creo.
QSharedDataPointer
- Este es un puntero inteligente "fuerte" potencialmente comparable, boost::intrusive_ptr
aunque tiene algo de seguridad de subproceso incorporado, pero requiere que incluyas métodos de conteo de referencia ( ref
y deref
) que puedes hacer subclasificando QSharedData
. Como con gran parte de Qt, los objetos se utilizan mejor a través de una amplia herencia y subclasificar todo parece ser el diseño previsto.
QExplicitlySharedDataPointer
- Muy similar a QSharedDataPointer
excepto que no llama implícitamente detach()
. Llamaría a esta versión 2.0, QSharedDataPointer
ya que ese ligero aumento en el control sobre exactamente cuándo separarse después de que el recuento de referencia caiga a cero no vale particularmente un objeto completamente nuevo.
QSharedPointer
- Cuenta de referencia atómica, hilo seguro, puntero para compartir, eliminaciones personalizadas (soporte de matriz), suena como todo lo que debería ser un puntero inteligente. Esto es lo que uso principalmente como un puntero inteligente en Qt y lo encuentro comparable con, boost:shared_ptr
aunque probablemente significativamente más sobrecarga como muchos objetos en Qt.
QWeakPointer
- ¿Sientes un patrón recurrente? Justo como std::weak_ptr
y boost::weak_ptr
esto se usa junto con QSharedPointer
cuando necesita referencias entre dos punteros inteligentes que de otra forma harían que sus objetos nunca se borren.
QScopedPointer
- Este nombre también debería parecer familiar y, de hecho, se basó a boost::scoped_ptr
diferencia de las versiones Qt de punteros compartidos y débiles. Funciona para proporcionar un puntero inteligente de un solo propietario sin la sobrecarga de QSharedPointer
lo que lo hace más adecuado para la compatibilidad, el código de excepción de seguridad y todas las cosas que puede usar std::auto_ptr
o boost::scoped_ptr
para las que puede usar .