La classe weak_ptr
Encapsule un pointeur faiblement lié.
Syntaxe
template<class T> class weak_ptr;
Paramètres
T
Type contrôlé par le pointeur faible.
Notes
Le modèle de classe décrit un objet qui pointe vers une ressource gérée par un ou plusieurs shared_ptr
objets. Les weak_ptr
objets qui pointent vers une ressource n’affectent pas le nombre de références de la ressource. Lorsque le dernier shared_ptr
objet qui gère cette ressource est détruit, la ressource est libérée, même s’il existe weak_ptr
des objets pointant vers cette ressource. Ce comportement est essentiel pour éviter les cycles dans les structures de données.
Un weak_ptr
objet pointe vers une ressource s’il a été construit à partir d’un shared_ptr
objet propriétaire de cette ressource, s’il a été construit à partir d’un weak_ptr
objet qui pointe vers cette ressource, ou si cette ressource a été affectée à cette ressource avec operator=
. Un weak_ptr
objet ne fournit pas d’accès direct à la ressource vers laquelle il pointe. Le code qui doit utiliser la ressource le fait par le biais d’un shared_ptr
objet propriétaire de cette ressource, créé en appelant la fonction lock
membre . Un weak_ptr
objet a expiré lorsque la ressource à laquelle il pointe a été libérée, car tous les shared_ptr
objets qui possèdent la ressource ont été détruits. L’appel lock
sur un weak_ptr
objet ayant expiré crée un objet vide shared_ptr
.
Un objet vide weak_ptr
ne pointe vers aucune ressource et n’a aucun bloc de contrôle. Sa fonction lock
membre retourne un objet vide shared_ptr
.
Un cycle se produit quand plusieurs ressources contrôlées par des objets shared_ptr
contiennent des objets shared_ptr
qui se font référence mutuellement. Par exemple, une liste circulaire liée avec trois éléments a un nœud principal N0
; ce nœud contient un objet shared_ptr
qui possède le nœud suivant, N1
; ce nœud contient un objet shared_ptr
qui possède le nœud suivant, N2
; ce nœud, à son tour, contient un objet shared_ptr
qui possède le nœud principal, N0
, ce qui ferme le cycle. Dans ce cas, les nombres de références ne deviennent jamais nuls, et les nœuds du cycle ne sont jamais libérés. Pour éliminer le cycle, le dernier nœud N2
doit contenir un objet weak_ptr
pointant vers N0
au lieu d'un objet shared_ptr
. Étant donné que l’objet weak_ptr
n’est pas propriétaire N0
, il n’affecte N0
pas le nombre de références et lorsque la dernière référence du programme au nœud principal est détruite, les nœuds de la liste seront également détruits.
Membres
Nom | Description |
---|---|
Constructeurs | |
weak_ptr |
Construit un objet weak_ptr . |
Destructeurs | |
~weak_ptr |
Détruit un weak_ptr . |
Typedefs | |
element_type |
Type de l'élément. |
Fonctions membres | |
expired |
Teste si la propriété a expiré. |
lock |
Obtient la propriété exclusive d'une ressource. |
owner_before |
Retourne true si ce weak_ptr est classé avant le pointeur fourni (ou est inférieur à celui-ci). |
reset |
Libère la ressource détenue. |
swap |
Échange deux objets weak_ptr . |
use_count |
Compte le nombre d’objets shared_ptr . |
Opérateurs | |
operator= |
Remplace la ressource détenue. |
element_type
Type de l'élément.
typedef T element_type; // through C++17
using element_type = remove_extent_t<T>; // C++20
Notes
Le type est un synonyme du paramètre de modèle T
.
Exemple
// std__memory__weak_ptr_element_type.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int(5));
std::weak_ptr<int> wp0(sp0);
std::weak_ptr<int>::element_type val = *wp0.lock();
std::cout << "*wp0.lock() == " << val << std::endl;
return (0);
}
*wp0.lock() == 5
expired
Teste si la propriété a expiré, autrement dit, l’objet référencé a été supprimé.
bool expired() const noexcept;
Notes
La fonction membre retourne true
si *this
a expiré, sinon false
.
Exemple
// std__memory__weak_ptr_expired.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wp;
{
std::shared_ptr<int> sp(new int(10));
wp = sp;
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
}
// check expired after sp is destroyed
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "(bool)wp.lock() == " << std::boolalpha
<< (bool)wp.lock() << std::endl;
return (0);
}
wp.expired() == false
*wp.lock() == 10
wp.expired() == true
(bool)wp.lock() == false
lock
Obtient un shared_ptr
partage de propriété d’une ressource.
shared_ptr<T> lock() const noexcept;
Notes
La fonction membre retourne un objet vide shared_ptr
s’il *this
a expiré ; sinon, il retourne un shared_ptr<T>
objet propriétaire de la ressource à *this
laquelle pointe. Retourne une valeur équivalente à l’exécution atomique de expired() ? shared_ptr<T>() : shared_ptr<T>(*this)
.
Exemple
// std__memory__weak_ptr_lock.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wp;
{
std::shared_ptr<int> sp(new int(10));
wp = sp;
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
}
// check expired after sp is destroyed
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
std::cout << "(bool)wp.lock() == " << std::boolalpha
<< (bool)wp.lock() << std::endl;
return (0);
}
wp.expired() == false
*wp.lock() == 10
wp.expired() == true
(bool)wp.lock() == false
operator=
Remplace la ressource détenue.
weak_ptr& operator=(const weak_ptr& ptr) noexcept;
template <class Other>
weak_ptr& operator=(const weak_ptr<Other>& ptr) noexcept;
template <class Other>
weak_ptr& operator=(const shared_ptr<Other>& ptr) noexcept;
Paramètres
Other
Type contrôlé par l’argument partagé ou le pointeur faible.
ptr
Pointeur faible ou pointeur partagé à copier.
Notes
Les opérateurs libèrent toutes la ressource actuellement pointée vers *this
et attribuent la propriété de la ressource nommée par ptr
*this
. En cas d’échec d’un opérateur, il reste *this
inchangé. Chaque opérateur a un effet équivalent à weak_ptr(ptr).swap(*this)
.
Exemple
// std__memory__weak_ptr_operator_as.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp0(new int(5));
std::weak_ptr<int> wp0(sp0);
std::cout << "*wp0.lock() == " << *wp0.lock() << std::endl;
std::shared_ptr<int> sp1(new int(10));
wp0 = sp1;
std::cout << "*wp0.lock() == " << *wp0.lock() << std::endl;
std::weak_ptr<int> wp1;
wp1 = wp0;
std::cout << "*wp1.lock() == " << *wp1.lock() << std::endl;
return (0);
}
*wp0.lock() == 5
*wp0.lock() == 10
*wp1.lock() == 10
owner_before
Retourne true
si ce weak_ptr
est classé avant le pointeur fourni (ou est inférieur à celui-ci).
template <class Other>
bool owner_before(const shared_ptr<Other>& ptr) const noexcept;
template <class Other>
bool owner_before(const weak_ptr<Other>& ptr) const noexcept;
Paramètres
ptr
Référence lvalue
à un shared_ptr
ou à un weak_ptr
.
Notes
La fonction membre du modèle retourne true
si *this
elle est ordonnée avant ptr
.
reset
Libère la ressource détenue.
void reset() noexcept;
Notes
La fonction membre libère la ressource pointée vers *this
et se *this
convertit en objet vide weak_ptr
.
Exemple
// std__memory__weak_ptr_reset.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp(new int(5));
std::weak_ptr<int> wp(sp);
std::cout << "*wp.lock() == " << *wp.lock() << std::endl;
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
wp.reset();
std::cout << "wp.expired() == " << std::boolalpha
<< wp.expired() << std::endl;
return (0);
}
*wp.lock() == 5
wp.expired() == false
wp.expired() == true
swap
Échange deux objets weak_ptr
.
void swap(weak_ptr& wp) noexcept;
Inclut également la spécialisation :
template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
Paramètres
wp
Pointeur faible à échanger.
Notes
Après un swap
, la ressource initialement pointée par *this
est pointée par wp
, et la ressource initialement pointée par est pointée par *this
wp
. La fonction ne modifie pas le nombre de références pour les deux ressources et ne lève aucune exception. L’effet de la spécialisation du modèle est l’équivalent de a.swap(b)
.
Exemple
// std__memory__weak_ptr_swap.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::shared_ptr<int> sp2(new int(10));
std::cout << "*sp1 == " << *sp1 << std::endl;
sp1.swap(sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
swap(sp1, sp2);
std::cout << "*sp1 == " << *sp1 << std::endl;
std::cout << std::endl;
std::weak_ptr<int> wp1(sp1);
std::weak_ptr<int> wp2(sp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
wp1.swap(wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
swap(wp1, wp2);
std::cout << "*wp1 == " << *wp1.lock() << std::endl;
return (0);
}
*sp1 == 5
*sp1 == 10
*sp1 == 5
*wp1 == 5
*wp1 == 10
*wp1 == 5
use_count
Compte le nombre d’objets shared_ptr
qui possèdent la ressource partagée.
long use_count() const noexcept;
Notes
La fonction membre retourne le nombre d’objets shared_ptr
qui détiennent la ressource désignée par *this
.
Exemple
// std__memory__weak_ptr_use_count.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::shared_ptr<int> sp1(new int(5));
std::weak_ptr<int> wp(sp1);
std::cout << "wp.use_count() == "
<< wp.use_count() << std::endl;
std::shared_ptr<int> sp2(sp1);
std::cout << "wp.use_count() == "
<< wp.use_count() << std::endl;
return (0);
}
wp.use_count() == 1
wp.use_count() == 2
weak_ptr
Construit un objet weak_ptr
.
constexpr weak_ptr() noexcept;
weak_ptr(const weak_ptr& wp) noexcept;
weak_ptr(weak_ptr&& wp) noexcept;
template <class Other>
weak_ptr(const weak_ptr<Other>& wp) noexcept;
template <class Other>
weak_ptr(weak_ptr<Other>&& sp) noexcept;
template <class Other>
weak_ptr(const shared_ptr<Other>& sp) noexcept;
Paramètres
Other
Type contrôlé par le pointeur partagé/faible d’argument. Ces constructeurs ne participent pas à la résolution de surcharge, sauf s’ils Other*
sont compatibles avec element_type*
.
wp
Pointeur faible à copier.
sp
Pointeur partagé à copier.
Notes
Le constructeur par défaut construit un objet vide weak_ptr
. Les constructeurs qui prennent un argument chaque construction d’un objet vide weak_ptr
si le pointeur d’argument est vide. Sinon, ils construisent un weak_ptr
objet qui pointe vers la ressource nommée par l’argument. Le nombre de références de l’objet partagé n’est pas modifié.
Exemple
// std__memory__weak_ptr_construct.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
int main()
{
std::weak_ptr<int> wp0;
std::cout << "wp0.expired() == " << std::boolalpha
<< wp0.expired() << std::endl;
std::shared_ptr<int> sp1(new int(5));
std::weak_ptr<int> wp1(sp1);
std::cout << "*wp1.lock() == "
<< *wp1.lock() << std::endl;
std::weak_ptr<int> wp2(wp1);
std::cout << "*wp2.lock() == "
<< *wp2.lock() << std::endl;
return (0);
}
wp0.expired() == true
*wp1.lock() == 5
*wp2.lock() == 5
~weak_ptr
Détruit un weak_ptr
.
~weak_ptr();
Notes
Le destructeur détruit cela weak_ptr
, mais n’a aucun effet sur le nombre de références de l’objet auquel pointe son pointeur stocké.
Voir aussi
Informations de référence sur les fichiers d’en-tête
<memory>
shared_ptr
, classe