Класс weak_ptr
Класс weak_ptr представляет собой
«слабую» ссылку на объект, которым владеет
shared_ptr. В отличие от shared_ptr,
weak_ptr не увеличивает счетчик ссылок
и не продлевает время жизни объекта. Он лишь
наблюдает за объектом и позволяет проверить,
существует ли он еще. Объект типа weak_ptr
создается из shared_ptr и не может быть
разыменован напрямую - для доступа к объекту
нужно получить временный shared_ptr
с помощью метода lock. Такой подход
позволяет избежать циклических зависимостей
между объектами, которые приводят к утечкам
памяти.
Синтаксис
#include <memory>
std::weak_ptr<T> ptr;
std::weak_ptr<T> ptr(shared_ptr);
std::weak_ptr<T> ptr = shared_ptr;
Пример
Давайте создадим shared_ptr на объект,
затем получим из него weak_ptr и
проверим, существует ли объект с помощью
метода lock:
#include <iostream>
#include <memory>
using namespace std;
int main()
{
shared_ptr<int> sp = make_shared<int>(42);
weak_ptr<int> wp = sp;
if (auto locked = wp.lock())
{
cout << *locked << endl;
}
else
{
cout << "Object is gone" << endl;
}
return 0;
}
Результат выполнения кода:
42
Пример
Давайте освободим shared_ptr и убедимся,
что weak_ptr видит, что объект больше
не существует:
#include <iostream>
#include <memory>
using namespace std;
int main()
{
weak_ptr<int> wp;
{
shared_ptr<int> sp = make_shared<int>(42);
wp = sp;
cout << (wp.expired() ? "alive" : "gone") << endl;
}
cout << (wp.expired() ? "gone" : "alive") << endl;
return 0;
}
Результат выполнения кода:
"alive"
"gone"
Пример
Давайте используем weak_ptr для
разрыва циклической зависимости между
двумя объектами. Класс Node хранит
weak_ptr на соседа, что не создает
владения:
#include <iostream>
#include <memory>
using namespace std;
struct Node
{
int value;
weak_ptr<Node> next;
Node(int v) : value(v) {}
};
int main()
{
auto a = make_shared<Node>(1);
auto b = make_shared<Node>(2);
a->next = b;
b->next = a;
if (auto locked = a->next.lock())
{
cout << locked->value << endl;
}
return 0;
}
Результат выполнения кода:
2