Sobes.tech
Middle

¿Cómo funciona shared_ptr en C++?

sobes.tech AI

Respuesta de la IA

shared_ptr — es un puntero inteligente que implementa la semántica de propiedad de un recurso compartido. Almacena un puntero al objeto y un puntero al bloque de control.

El bloque de control contiene:

  • Contador de referencias fuertes (reference count).
  • Contador de referencias débiles (weak count).
  • Funcor de eliminación personalizado (deleter), si se especifica.
  • Allocador personalizado, si se especifica.
  • Puntero al objeto almacenado (lo mismo que se almacena en el shared_ptr).

Principio de funcionamiento:

  1. Creación: Al crear el primer shared_ptr que apunta a un objeto, se crea el bloque de control, y los contadores de referencias se inicializan: fuertes — 1, débiles — 0.
    std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Crea un objeto int y un bloque de control
    
  2. Copia: Al copiar un shared_ptr, el contador de referencias fuertes en el bloque de control aumenta en 1.
    std::shared_ptr<int> ptr2 = ptr1; // Aumenta el contador de referencias fuertes
    
  3. Asignación: Al asignar un shared_ptr, el recurso antiguo se decrementa (disminuye el contador de referencias fuertes), y el nuevo recurso se incrementa (aumenta el contador).
    std::shared_ptr<int> ptr3;
    ptr3 = ptr1; // Decrementa el recurso antiguo de ptr3, Incrementa el recurso de ptr1
    
  4. Eliminación: Al destruir un shared_ptr (por ejemplo, salir del ámbito), el contador de referencias fuertes se decrementa.
    {
        std::shared_ptr<int> ptr4 = ptr1; // Aumenta el contador de referencias fuertes
        // ptr4 sale del ámbito
    } // Decrementa el contador de referencias fuertes
    
  5. Liberación del recurso: Cuando el contador de referencias fuertes llega a cero, el recurso (el objeto apuntado por shared_ptr) se elimina usando el functor de eliminación definido (o delete por defecto).
  6. Liberación del bloque de control: El bloque de control se libera cuando ambos contadores (fuertes y débiles) alcanzan cero.

Ventajas:

  • Gestión automática de memoria para recursos compartidos.
  • Seguridad contra liberaciones dobles.
  • Soporte para functors de eliminación personalizados.

Desventajas:

  • Los enlaces cíclicos pueden causar fugas de memoria (resuelto con weak_ptr).
  • Pequeño aumento en los costos debido al bloque de control y operaciones atómicas en los contadores.
  • Seguridad en operaciones con el propio shared_ptr (copiar, asignar, cambiar el puntero almacenado), pero no con el objeto al que apunta.