Saltar al contenido principal
eLearner.app
Módulo 7 · Lección 2 de 216/18 en el curso~12 min
Lecciones del módulo (2/2)

std::weak_ptr

Aunque std::shared_ptr es extremadamente útil, el uso exclusivo de la propiedad compartida puede provocar un problema conocido como referencia cíclica (o cyclic dependency).

Si dos o más objetos contienen cada uno un shared_ptr que apunta al otro, se crea un ciclo cerrado. En esta situación, el contador de referencias de ninguno de los dos objetos llegará a cero, lo que impide la liberación de memoria y genera una fuga de memoria (memory leak).

¿Qué es std::weak_ptr?

Para romper los ciclos de propiedad, la biblioteca estándar ofrece std::weak_ptr. Se trata de un puntero inteligente que observa un objeto gestionado por un shared_ptr, pero sin incrementar el reference count.

No posee directamente el recurso, por lo que no impide su destrucción.

Code
#include <memory>

std::shared_ptr<int> shared = std::make_shared<int>(42);
std::weak_ptr<int> weak = shared; // Non incrementa il contatore!

Verificar y Acceder al Recurso

Dado que un weak_ptr no posee el recurso, este podría liberarse en cualquier momento (cuando todos los shared_ptr asociados salen del ámbito).

Para utilizar el recurso observado, primero debemos:

  1. Comprobar si todavía es válido usando expired().
  2. Convertir temporalmente el weak_ptr en un shared_ptr mediante el método lock(). Si el recurso sigue activo, lock() devuelve un shared_ptr válido; de lo contrario, devuelve un puntero nulo (nullptr).
Code
if (!weak.expired()) {
    // lock() crea uno shared_ptr temporaneo per garantire l'accesso sicuro
    if (std::shared_ptr<int> sharedAccess = weak.lock()) {
        std::cout << *sharedAccess << std::endl;
    }
} else {
    std::cout << "Risorsa deallocata!" << std::endl;
}

Pruébalo tú mismo

Ejercicio#cpp.m7.l2.e1
Intentos: 0Cargando...

Declara un std::weak_ptr<int> llamado wPtr inicializado a partir de sPtr. Después imprime el resultado booleano devuelto por wPtr.expired() usando std::cout.

Cargando editor...
Mostrar pista

Declara el `weak_ptr` indicando el mismo tipo genérico `<int>` y asígnale directamente `sPtr`.

Solución disponible después de 3 intentos

Ejercicio#cpp.m7.l2.e2
Intentos: 0Cargando...

Usa el método lock() en wPtr para obtener un shared_ptr temporal. Si la operación tiene éxito (el puntero no es nulo), imprime en pantalla el valor dereferenciado.

Cargando editor...
Mostrar pista

Inicializa una variable dentro de un bloque `if` llamando a `wPtr.lock()`, luego imprime el recurso dereferenciándolo con el asterisco `*`.

Solución disponible después de 3 intentos