Класс weak_ptr
Создает оболочку слабо связанного указателя.
Синтаксис
template<class T> class weak_ptr;
Параметры
T
Тип, управляемый слабым указателем.
Замечания
Шаблон класса описывает объект, указывающий на ресурс, управляемый одним или несколькими shared_ptr
объектами. Объекты weak_ptr
, указывающие на ресурс, не влияют на количество ссылок ресурса. Когда последний shared_ptr
объект, который управляет этим ресурсом, будет освобожден, даже если есть weak_ptr
объекты, указывающие на этот ресурс. Это поведение важно для предотвращения циклов в структурах данных.
weak_ptr
Объект указывает на ресурс, если он был создан из объекта, которому принадлежит этот ресурс, если он был создан из shared_ptr
weak_ptr
объекта, указывающего на этот ресурс, или если этот ресурс был назначен ему.operator=
Объект weak_ptr
не предоставляет прямой доступ к ресурсу, на который он указывает. Код, который должен использовать ресурс, делает это с помощью объекта, который владеет этим ресурсом shared_ptr
, созданный путем вызова функции-члена lock
. Срок weak_ptr
действия объекта истек, когда ресурс, на который он указывает, был освобожден из-за того, что все shared_ptr
объекты, принадлежащие ресурсу, были уничтожены. Вызов lock
объекта, истекший срок действия, создает пустой shared_ptr
weak_ptr
объект.
Пустой weak_ptr
объект не указывает на ресурсы и не имеет блока управления. Его функция-член lock
возвращает пустой shared_ptr
объект.
Цикл происходит, если два или более ресурсов, управляемых объектами shared_ptr
содержат ссылающиеся друг на друга объекты shared_ptr
. Например, цикличный связанный список с тремя элементами содержит головной узел N0
; этот узел включает объект shared_ptr
, который владеет следующим узлом, N1
; этот узел содержит объект shared_ptr
, который владеет следующим узлом, N2
; этот узел, в свою очередь, содержит объект shared_ptr
, который владеет головным узлом N0
, что создает цикл. В этой ситуации количество ссылок никогда не становится нулевым, а узлы в цикле никогда не освобождаются. Чтобы исключить цикл, последний узел N2
должен содержать объект weak_ptr
, указывающий на N0
, а не объект shared_ptr
. weak_ptr
Так как объект не владеет N0
им, он не влияет на N0
число ссылок, и когда последняя ссылка программы на головной узел уничтожается, узлы в списке также будут уничтожены.
Участники
Имя | Описание |
---|---|
Конструкторы | |
weak_ptr |
Создает документ weak_ptr . |
Деструкторы | |
~weak_ptr |
Удаляет weak_ptr . |
Typedefs | |
element_type |
Тип элемента. |
Функции-члены | |
expired |
Проверяет, истек ли срок действия владения. |
lock |
Получает эксклюзивные права владения ресурсом. |
owner_before |
Возвращает true , если этот объект weak_ptr заказывался раньше заданного указателя (или меньше него). |
reset |
Освобождает ресурс, которым владеет. |
swap |
Меняет местами два объекта weak_ptr . |
use_count |
Подсчитывает количество shared_ptr объектов. |
Операторы | |
operator= |
Заменяет ресурс, которым владеет. |
element_type
Тип элемента.
typedef T element_type; // through C++17
using element_type = remove_extent_t<T>; // C++20
Замечания
Этот тип является синонимом для параметра шаблона T
.
Пример
// 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
Проверяет, истек ли срок владения, то есть объект, на который ссылается ссылка, был удален.
bool expired() const noexcept;
Замечания
Функция-член возвращает true
, если срок владения *this
истек, в противном случае false
.
Пример
// 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
shared_ptr
Получает право владения ресурсом.
shared_ptr<T> lock() const noexcept;
Замечания
Функция-член возвращает пустой shared_ptr
объект, если *this
истек срок действия; в противном случае возвращает shared_ptr<T>
объект, которому принадлежит ресурс, *this
на который указывает ресурс. Возвращает значение, эквивалентное атомарного выполнения expired() ? shared_ptr<T>() : shared_ptr<T>(*this)
.
Пример
// 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=
Заменяет ресурс, которым владеет.
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;
Параметры
Other
Тип, управляемый общим или слабым указателем аргумента.
ptr
Слабый указатель или общий указатель для копирования.
Замечания
Все операторы освобождают ресурс, на который указывает *this
текущий ресурс, и присваивают права владения ресурсом, именованным в ptr
*this
. Если оператор завершается ошибкой, он остается *this
неизменным. Каждый оператор имеет эффект, эквивалентный weak_ptr(ptr).swap(*this)
.
Пример
// 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
Возвращает true
, если этот объект weak_ptr
заказывался раньше заданного указателя (или меньше него).
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;
Параметры
ptr
Ссылка lvalue
на значение shared_ptr
или weak_ptr
.
Замечания
Функция-член шаблона возвращается true
, если *this
он упорядочен до ptr
.
reset
Освобождает принадлежащий ресурс.
void reset() noexcept;
Замечания
Функция-член освобождает ресурс, на который указывает *this
ресурс, и преобразуется *this
в пустой weak_ptr
объект.
Пример
// 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
Меняет местами два объекта weak_ptr
.
void swap(weak_ptr& wp) noexcept;
Также включает специализацию:
template<class T>
void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
Параметры
wp
Слабый указатель, который будет заменен.
Замечания
swap
После того, как ресурс первоначально указывает *this
на, указывает wp
на , и ресурс, на который первоначально указываетсяwp
, указывает на *this
. Функция не изменяет количество ссылок для двух ресурсов и не создает никаких исключений. Эффект специализации шаблона эквивалентен a.swap(b)
.
Пример
// 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
Подсчитывает количество объектов, принадлежащих shared_ptr
общему ресурсу.
long use_count() const noexcept;
Замечания
Функция-член возвращает число объектов shared_ptr
, которые являются владельцем ресурса, на который указывает *this
.
Пример
// 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
Создает документ 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;
Параметры
Other
Тип, которым управляет общий или слабый указатель на аргумент. Эти конструкторы не участвуют в разрешении перегрузки, если Other*
не совместим с element_type*
.
wp
Слабый указатель для копирования.
sp
Общий указатель для копирования.
Замечания
Конструктор по умолчанию создает пустой weak_ptr
объект. Конструкторы, которые принимают аргумент каждый из них, создают пустой объект, если указатель аргумента пуст weak_ptr
. В противном случае они создают объект, указывающий weak_ptr
на ресурс с именем аргумента. Количество ссылок общего объекта не изменяется.
Пример
// 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
Удаляет weak_ptr
.
~weak_ptr();
Замечания
Деструктор уничтожает это weak_ptr
, но не влияет на число ссылок объекта, на который он находится.