Classe weak_ptr
Esegue il wrapping di un puntatore collegato in modo debole.
Sintassi
template<class T> class weak_ptr;
Parametri
T
Tipo controllato dal puntatore debole.
Osservazioni:
Il modello di classe descrive un oggetto che punta a una risorsa gestita da uno o più shared_ptr
oggetti. Gli weak_ptr
oggetti che puntano a una risorsa non influiscono sul conteggio dei riferimenti della risorsa. Quando l'ultimo shared_ptr
oggetto che gestisce tale risorsa viene eliminato definitivamente, la risorsa verrà liberata, anche se sono weak_ptr
presenti oggetti che puntano a tale risorsa. Questo comportamento è essenziale per evitare cicli nelle strutture di dati.
Un weak_ptr
oggetto punta a una risorsa se è stata costruita da un shared_ptr
oggetto proprietario di tale risorsa, se è stato costruito da un weak_ptr
oggetto che punta a tale risorsa o se tale risorsa è stata assegnata con operator=
. Un weak_ptr
oggetto non fornisce l'accesso diretto alla risorsa a cui punta. Il codice che deve usare la risorsa esegue questa operazione tramite un shared_ptr
oggetto proprietario di tale risorsa, creato chiamando la funzione lock
membro . Un weak_ptr
oggetto è scaduto quando la risorsa a cui punta è stata liberata perché tutti gli shared_ptr
oggetti proprietari della risorsa sono stati eliminati definitivamente. La chiamata lock
a un weak_ptr
oggetto scaduto crea un oggetto vuoto shared_ptr
.
Un oggetto vuoto weak_ptr
non punta ad alcuna risorsa e non ha alcun blocco di controllo. La funzione lock
membro restituisce un oggetto vuoto shared_ptr
.
Si verifica un ciclo quando due o più risorse controllate da oggetti shared_ptr
contengono oggetti shared_ptr
che fanno riferimento uno con l'altro. Ad esempio, un elenco collegato circolare con tre elementi ha un nodo head N0
, tale nodo contiene un oggetto shared_ptr
proprietario del nodo successivo N1
, tale nodo contiene un oggetto shared_ptr
proprietario del nodo successivo N2
e tale nodo, a sua volta, contiene un oggetto shared_ptr
proprietario del nodo head N0
, che chiude il ciclo. In questa situazione, i conteggi dei riferimenti non diventano mai zero e i nodi del ciclo non vengono mai liberati. Per eliminare il ciclo, l'ultimo nodo N2
deve contenere un oggetto weak_ptr
che punta all'oggetto N0
anziché un oggetto shared_ptr
. Poiché l'oggetto weak_ptr
non è proprietario N0
, non influisce sul N0
conteggio dei riferimenti e, quando l'ultimo riferimento al nodo head del programma viene eliminato definitivamente, i nodi nell'elenco verranno eliminati definitivamente.
Membri
Nome | Descrizione |
---|---|
Costruttori | |
weak_ptr |
Costruisce un oggetto weak_ptr . |
Distruttori | |
~weak_ptr |
Elimina un oggetto weak_ptr . |
Typedef | |
element_type |
Tipo dell'elemento. |
Funzioni membro | |
expired |
Verifica se la proprietà è scaduta. |
lock |
Ottiene la proprietà esclusiva di una risorsa. |
owner_before |
Restituisce true se weak_ptr è ordinato in posizione precedente al (o è minore del) puntatore fornito. |
reset |
Rilascia una risorsa di proprietà. |
swap |
Scambia due oggetti weak_ptr . |
use_count |
Conta il numero di shared_ptr oggetti. |
Operatori | |
operator= |
Sostituisce una risorsa di proprietà. |
element_type
Tipo dell'elemento.
typedef T element_type; // through C++17
using element_type = remove_extent_t<T>; // C++20
Osservazioni:
Il tipo è un sinonimo del parametro di modello T
.
Esempio
// 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
Verifica se la proprietà è scaduta, ovvero l'oggetto a cui si fa riferimento è stato eliminato.
bool expired() const noexcept;
Osservazioni:
La funzione membro restituisce true
se *this
è scaduto, altrimenti restituisce false
.
Esempio
// 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
Ottiene un oggetto shared_ptr
che condivide la proprietà di una risorsa.
shared_ptr<T> lock() const noexcept;
Osservazioni:
La funzione membro restituisce un oggetto vuoto shared_ptr
se *this
è scaduto; in caso contrario, restituisce un shared_ptr<T>
oggetto proprietario della risorsa a cui *this
punta. Restituisce un valore equivalente all'esecuzione atomica di expired() ? shared_ptr<T>() : shared_ptr<T>(*this)
.
Esempio
// 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=
Sostituisce una risorsa di proprietà.
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;
Parametri
Other
Tipo controllato dall'argomento condiviso o dal puntatore debole.
ptr
Puntatore debole o puntatore condiviso da copiare.
Osservazioni:
Tutti gli operatori rilasciano la risorsa a *this
cui punta e assegnano la proprietà della risorsa denominata da ptr
a *this
. Se un operatore non riesce, rimane *this
invariato. Ogni operatore ha un effetto equivalente a weak_ptr(ptr).swap(*this)
.
Esempio
// 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
Restituisce true
se weak_ptr
è ordinato in posizione precedente al (o è minore del) puntatore fornito.
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;
Parametri
ptr
Riferimento lvalue
a shared_ptr
o weak_ptr
.
Osservazioni:
La funzione membro del modello restituisce true
se *this
è ordinato prima ptr
di .
reset
Rilascia la risorsa di proprietà.
void reset() noexcept;
Osservazioni:
La funzione membro rilascia la risorsa a *this
cui punta e converte *this
in un oggetto vuoto weak_ptr
.
Esempio
// 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
Scambia due oggetti weak_ptr
.
void swap(weak_ptr& wp) noexcept;
Include anche la specializzazione:
template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
Parametri
wp
Puntatore debole da scambiare.
Osservazioni:
Dopo un swap
oggetto , la risorsa a cui punta *this
originariamente fa riferimento viene puntata da wp
e la risorsa a wp
cui punta originariamente fa riferimento .*this
La funzione non modifica i conteggi dei riferimenti per le due risorse e non genera eccezioni. L'effetto della specializzazione del modello è l'equivalente di a.swap(b)
.
Esempio
// 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
Conta il numero di shared_ptr
oggetti proprietari della risorsa condivisa.
long use_count() const noexcept;
Osservazioni:
La funzione membro restituisce il numero di oggetti shared_ptr
che possiedono la risorsa a cui puntava *this
.
Esempio
// 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
Costruisce un oggetto 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;
Parametri
Other
Tipo controllato dal puntatore dell'argomento condiviso/debole. Questi costruttori non partecipano alla risoluzione dell'overload, a meno che Other*
non sia compatibile con element_type*
.
wp
Puntatore debole da copiare.
sp
Puntatore condiviso da copiare.
Osservazioni:
Il costruttore predefinito costruisce un oggetto vuoto weak_ptr
. I costruttori che accettano un argomento costruiscono un oggetto vuoto weak_ptr
se il puntatore dell'argomento è vuoto. In caso contrario, creano un weak_ptr
oggetto che punta alla risorsa denominata dall'argomento . Il numero di riferimenti dell'oggetto condiviso non viene modificato.
Esempio
// 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
Elimina un oggetto weak_ptr
.
~weak_ptr();
Osservazioni:
Il distruttore elimina questo weak_ptr
valore, ma non ha alcun effetto sul conteggio dei riferimenti dell'oggetto in corrispondenza dei punti del puntatore archiviati.