Sur quelle base plusieurs objets shared_ptr peuvent-ils faire référence au même pointeur?
sobes.tech IA
Réponse de l'IA
Plusieurs objets std::shared_ptr peuvent faire référence au même pointeur grâce à l'existence d'un bloc de contrôle (control block).
Le bloc de contrôle associé à l'objet géré contient :
- Compteur de références fortes (strong reference count) : Augmente lors de la création d'un nouveau
shared_ptrpour le même objet. Diminue lors de la destruction d'unshared_ptr. Lorsqu'il atteint zéro, l'objet (pointeur) associé est supprimé. - Compteur de références faibles (weak reference count) : Utilisé pour
std::weak_ptr. Augmente lors de la création d'unweak_ptrà partir d'unshared_ptr. Diminue lors de la destruction d'unweak_ptr. Lorsqu'ils atteignent tous deux zéro, le bloc de contrôle est supprimé. - Pointeur propre vers l'objet géré : Pas le pointeur de données lui-même, mais celui qui est géré par le bloc.
Lorsque vous créez un shared_ptr à partir d'un autre existant (copie, affectation-copie), ils commencent à utiliser le même bloc de contrôle, et le compteur de références fortes dans ce bloc augmente.
Exemple :
#include <memory>
#include <iostream>
struct MyData {
int value;
MyData(int v) : value(v) { std::cout << "MyData(" << value << ") créé.\n"; }
~MyData() { std::cout << "MyData(" << value << ") détruit.\n"; }
};
int main() {
// Création du premier shared_ptr.
// Création du bloc de contrôle et de l'objet MyData.
// Compteurs strong : 1, weak : 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "compteur d'utilisation de ptr1 : " << ptr1.use_count() << "\n";
// Création d'un second shared_ptr à partir de ptr1.
// Utilise le même bloc de contrôle.
// Le compteur strong augmente à 2.
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "compteur d'utilisation de ptr1 : " << ptr1.use_count() << "\n";
std::cout << "compteur d'utilisation de ptr2 : " << ptr2.use_count() << "\n";
// Création d'un troisième shared_ptr à partir de ptr1.
// Utilise le même bloc de contrôle.
// Le compteur strong augmente à 3.
std::shared_ptr<MyData> ptr3 = ptr1;
std::cout << "compteur d'utilisation de ptr1 : " << ptr1.use_count() << "\n";
std::cout << "compteur d'utilisation de ptr2 : " << ptr2.use_count() << "\n";
std::cout << "compteur d'utilisation de ptr3 : " << ptr3.use_count() << "\n";
std::cout << "Sortie du scope.\n";
// ptr3 sort de la portée.
// Le compteur strong diminue à 2.
// ptr2 sort de la portée.
// Le compteur strong diminue à 1.
// ptr1 sort de la portée.
// Le compteur strong diminue à 0.
// L'objet MyData est détruit.
// Le bloc de contrôle est détruit.
}
Chaque objet shared_ptr contient son propre pointeur vers le bloc de contrôle et son propre pointeur vers l'objet de données. Lors de la copie d'un shared_ptr, les deux pointeurs sont copiés, et le compteur de références fortes dans le bloc commun est incrémenté. Ainsi, tous les shared_ptr pointent vers le même bloc de contrôle, qui suit le nombre de ses copies possédant la ressource et détermine le moment de destruction de la ressource gérée.