Passer au contenu principal
eLearner.app
Module 7 · Leçon 2 sur 216/18 dans le cours~12 min
Leçons du module (2/2)

std::weak_ptr

Bien que std::shared_ptr soit extrêmement utile, l'utilisation exclusive de la propriété partagée peut entraîner un problème connu sous le nom de référence cyclique (ou cyclic dependency).

Si deux objets ou plus contiennent chacun un shared_ptr qui pointe vers l'autre, un cycle fermé se crée. Dans cette situation, le compteur de références d'aucun des deux objets ne descendra jamais à zéro, empêchant la désallocation et provoquant une fuite de mémoire (memory leak).

Qu'est-ce que std::weak_ptr ?

Pour casser les cycles de propriété, la bibliothèque standard propose std::weak_ptr. Il s'agit d'un pointeur intelligent qui observe un objet géré par un shared_ptr, mais sans incrémenter le reference count.

Il ne possède pas directement la ressource, il n'empêche donc pas sa destruction.

Code
#include <memory>

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

Vérifier et accéder à la ressource

Comme un weak_ptr ne possède pas la ressource, celle-ci peut être désallouée à tout moment (lorsque tous les shared_ptr associés sortent de la portée).

Pour utiliser la ressource observée, nous devons d'abord :

  1. Vérifier si elle est toujours valide à l'aide de expired().
  2. Convertir temporairement le weak_ptr en un shared_ptr via la méthode lock(). Si la ressource est toujours active, lock() renvoie un shared_ptr valide, sinon elle renvoie un pointeur nul (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;
}

À vous de jouer

Exercice#cpp.m7.l2.e1
Tentatives : 0Chargement…

Déclarez un std::weak_ptr<int> nommé wPtr initialisé à partir de sPtr. Affichez ensuite le résultat booléen renvoyé par wPtr.expired() à l'aide de std::cout.

Chargement de l'éditeur…
Afficher l'indice

Déclarez le `weak_ptr` en indiquant le même type générique `<int>` et affectez-lui directement `sPtr`.

Solution disponible après 3 tentatives

Exercice#cpp.m7.l2.e2
Tentatives : 0Chargement…

Utilisez la méthode lock() sur wPtr pour obtenir un shared_ptr temporaire. Si l'opération réussit (le pointeur n'est pas nul), affichez à l'écran la valeur déréférencée.

Chargement de l'éditeur…
Afficher l'indice

Initialisez une variable à l'intérieur d'un bloc `if` en appelant `wPtr.lock()`, puis affichez la ressource en la déréférençant avec l'astérisque `*`.

Solution disponible après 3 tentatives