Diferencias entre el rpp único y el rpp compartido [duplicado]


Posibles Duplicados:
pimpl: shared_ptr o unique_ptr
punteros inteligentes (boost) explicó

¿Podría alguien explicar las diferencias entre shared_ptr y unique_ptr?

Author: Community, 2011-07-29

4 answers

Ambas clases son punteros inteligentes, lo que significa que automáticamente (en la mayoría de los casos) desasignarán el objeto al que apuntan cuando ya no se pueda hacer referencia a ese objeto. La diferencia entre los dos es cuántos punteros diferentes de cada tipo pueden referirse a un recurso.

Cuando se usa unique_ptr, puede haber como máximo un unique_ptr apuntando a cualquier recurso. Cuando se destruye ese unique_ptr, el recurso se recupera automáticamente. Porque solo puede haber uno unique_ptr para cualquier recurso, cualquier intento de hacer una copia de un unique_ptr causará un error en tiempo de compilación. Por ejemplo, este código es ilegal:

unique_ptr<T> myPtr(new T);       // Okay
unique_ptr<T> myOtherPtr = myPtr; // Error: Can't copy unique_ptr

Sin embargo, unique_ptr puede ser movido usando la nueva semántica de movimiento:

unique_ptr<T> myPtr(new T);                  // Okay
unique_ptr<T> myOtherPtr = std::move(myPtr); // Okay, resource now stored in myOtherPtr

De manera similar, puedes hacer algo como esto: {[18]]}

unique_ptr<T> MyFunction() {
    unique_ptr<T> myPtr(/* ... */);

    /* ... */

    return myPtr;
}

Este modismo significa "Te estoy devolviendo un recurso administrado. Si no captura explícitamente el valor devuelto, el recurso se limpiará. Si lo hace, entonces ahora tiene la propiedad exclusiva de ese recurso."De esta manera, puedes pensar en unique_ptr como un reemplazo más seguro y mejor para auto_ptr.

shared_ptr, por otro lado, permite que varios punteros apunten a un recurso dado. Cuando el último shared_ptr de un recurso es destruido, el recurso será desasignado. Por ejemplo, este código es perfectamente legal:

shared_ptr<T> myPtr(new T);       // Okay
shared_ptr<T> myOtherPtr = myPtr; // Sure!  Now have two pointers to the resource.

Internamente, shared_ptr usa conteo de referencias para rastrear cuántos punteros se refieren a un recurso, por lo que debe tener cuidado de no introducir ninguno ciclos de referencia.

En breve:

  1. Use unique_ptr cuando desee un solo puntero a un objeto que se recuperará cuando se destruya ese único puntero.
  2. Use shared_ptr cuando desee varios punteros al mismo recurso.

Espero que esto ayude!

 384
Author: templatetypedef,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-06 19:56:41

unique_ptr es el puntero inteligente ligero de elección si solo tiene un objeto dinámico en algún lugar para el cual un consumidor tiene responsabilidad única (por lo tanto "única") maybe tal vez una clase de envoltura que necesita mantener algún objeto asignado dinámicamente. unique_ptr tiene muy poca sobrecarga. No es copiable, sino móvil. Su tipo es template <typename D, typename Deleter> class unique_ptr;, por lo que depende de dos parámetros de plantilla.

unique_ptr es también lo que auto_ptr quería estar en el viejo C++ pero no pudo porque de las limitaciones de ese lenguaje.

shared_ptr por otro lado, es un animal muy diferente. La diferencia obvia es que puede tener muchos consumidores compartiendo la responsabilidad de un objeto dinámico (por lo tanto, "compartido"), y el objeto solo se destruirá cuando todos los punteros compartidos se hayan ido. Adicionalmente puede tener observing weak pointers que serán informados inteligentemente si el puntero compartido que están siguiendo ha desaparecido.

Internamente, shared_ptr tiene mucho más continúa: Hay un recuento de referencias, que se actualiza atómicamente para permitir el uso en código concurrente. Además, hay mucha asignación, una para un "bloque de control de referencia" de contabilidad interna, y otra (a menudo) para el objeto miembro real.

Pero hay otra gran diferencia: El tipo de punteros compartidos es siempre template <typename T> class shared_ptr;, y esto es a pesar del hecho de que puede inicializarlo con deleters personalizados y con asignadores personalizados. El deleter y los asignadores se rastrean utilizando el tipo borrado y el envío de funciones virtuales, lo que aumenta el peso interno de la clase, pero tiene la enorme ventaja de que los diferentes tipos de punteros compartidos de tipo T son compatibles, sin importar los detalles de eliminación y asignación. Por lo tanto, realmente expresan el concepto de "responsabilidad compartida para T" sin cargar al consumidor con los detalles!

Tanto shared_ptr como unique_ptr están diseñados para ser pasados por valor (con la movilidad obvia requisito para el puntero único). Ninguno de los dos debería preocuparle por la sobrecarga, ya que su poder es realmente asombroso, pero si tiene una opción, prefiera unique_ptr, y solo use shared_ptr si realmente necesita una responsabilidad compartida.

 60
Author: Kerrek SB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-01 10:31:37

Unique_ptr
es un puntero inteligente que posee un objeto exclusivamente.

Shared_ptr
es un puntero inteligente para la propiedad compartida. Es a la vez copyable y movable. Varias instancias de puntero inteligente pueden poseer el mismo recurso. Tan pronto como el último puntero inteligente que posee el recurso salga del alcance, el recurso se liberará.

 12
Author: Alok Save,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-29 17:32:02

Al envolver un puntero en un unique_ptr no puede tener varias copias de unique_ptr. El shared_ptr contiene un contador de referencia que cuenta el número de copias del puntero almacenado. Cada vez que se copia un shared_ptr, este contador se incrementa. Cada vez que se destruye un shared_ptr, este contador se decrementa. Cuando este contador alcanza 0, el objeto almacenado se destruye.

 6
Author: neodelphi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-29 06:12:39