std::weak_ptr
| Определено в заголовочном файле <memory>
|
||
template< class T > class weak_ptr; |
(начиная с C++11) | |
std::weak_ptr это умный указатель, который содержит не являющуюся владельцем "слабую" ссылку на объект, которым управляет std::shared_ptr. Чтобы получить доступ к управляемому объекту, указатель необходимо привести к типу std::shared_ptr, .
std::weak_ptr моделирует временное владение: когда объект должен быть доступен только если он существует и может быть удалён в любой момент кем-то другим, std::weak_ptr используется для отслеживания объекта, и преобразуется в std::shared_ptr для принятия временного владения. Если исходный std::shared_ptr будет уничтожен в процессе работы, время жизни объекта продлевается до того момента, пока не будет разрушен временный std::shared_ptr.
Другое применение std::weak_ptr это устранение циклических ссылок, сформированных объектами, управляемыми std::shared_ptr. Если такая циклическая ссылка осиротела (т.е. в цикле нет внешних общих указателей), счётчик ссылок shared_ptr не может достичь нуля, и происходит утечка памяти. Чтобы этого не произошло, один из указателей в цикле можно сделать слабым.
Типы-элементы
| Тип элемент | Определение | ||||
element_type
|
| ||||
Функции-элементы
создаёт новый weak_ptr (public функция-элемент) | |
уничтожает weak_ptr (public функция-элемент) | |
присваивает weak_ptr (public функция-элемент) | |
Модификаторы | |
| прекращает владение управляемым объектом (public функция-элемент) | |
| меняет местами управляемые объекты (public функция-элемент) | |
Наблюдатели | |
возвращает количество объектов shared_ptr, которые управляют объектом (public функция-элемент) | |
| проверяет, был ли удалён объект, на который ссылается weak_ptr (public функция-элемент) | |
создаёт shared_ptr, который управляет объектом, на который ссылается weak_ptr (public функция-элемент) | |
| обеспечивает упорядочивание слабых указателей на основе владельцев (public функция-элемент) | |
Функции, не являющиеся элементами
(C++11) |
специализация алгоритма std::swap (шаблон функции) |
Вспомогательные классы
(C++20) |
атомарный слабый указатель (специализация шаблона класса) |
Правила вывода (начиная с C++17)
Примечание
Подобно std::shared_ptr, типичная реализация weak_ptr хранит два указателя:
- указатель на блок управления; и
- сохранённый указатель
shared_ptr, из которого он был создан.
Отдельный сохранённый указатель необходим для того, чтобы преобразование shared_ptr в weak_ptr, а затем обратно работало правильно, даже для псевдонимов shared_ptr. Невозможно получить доступ к сохранённому указателю в weak_ptr без блокировки его в shared_ptr.
| Макрос Тестирования функциональности | Значение | Стандарт | Функциональность |
|---|---|---|---|
__cpp_lib_smart_ptr_owner_equality |
202306L |
(C++26) | Включение использования std::weak_ptr в качестве ключей в нет названия раздела
|
Пример
Демонстрирует, как блокировка используется для обеспечения действительности указателя.
#include <iostream>
#include <memory>
std::weak_ptr<int> gw;
void observe()
{
std::cout << "gw.use_count() == " << gw.use_count() << "; ";
// мы должны сделать копию общего указателя перед использованием:
if (std::shared_ptr<int> spt = gw.lock()) {
std::cout << "*spt == " << *spt << '\n';
}
else {
std::cout << "gw истёк\n";
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
observe();
}
observe();
}
Вывод:
gw.use_count() == 1; *spt == 42
gw.use_count() == 0; gw истёк
Отчёты о дефектах
Следующие изменения поведения были применены с обратной силой к ранее опубликованным стандартам C++:
| Номер | Применён | Поведение в стандарте | Корректное поведение |
|---|---|---|---|
| LWG 3001 | C++17 | element_type не был обновлён для поддержки массива
|
обновлён |
Смотрите также
(C++11) |
умный указатель с уникальной семантикой владения объектом (шаблон класса) |
(C++11) |
умный указатель с семантикой владения разделяемым объектом (шаблон класса) |