Ответ
Циклическая зависимость возникает, когда два или более объекта, управляемых std::shared_ptr, хранят взаимные ссылки, что препятствует освобождению памяти, так как счётчик ссылок никогда не достигает нуля. std::weak_ptr решает эту проблему, так как он не увеличивает счётчик ссылок объекта, на который указывает.
Пример:
#include <iostream>
#include <memory>
class NodeB;
class NodeA {
public:
std::shared_ptr<NodeB> b_ptr;
~NodeA() { std::cout << "NodeA destroyedn"; }
};
class NodeB {
public:
// Используем weak_ptr, чтобы разорвать цикл
std::weak_ptr<NodeA> a_weak_ptr;
~NodeB() { std::cout << "NodeB destroyedn"; }
};
int main() {
auto a = std::make_shared<NodeA>();
auto b = std::make_shared<NodeB>();
a->b_ptr = b; // b увеличивает счётчик ссылок на NodeB
b->a_weak_ptr = a; // a передаётся как weak_ptr, счётчик NodeA не увеличивается
// При выходе из области видимости объекты будут корректно уничтожены
return 0;
}
Ключевые моменты:
weak_ptrсоздаётся изshared_ptr.- Для доступа к объекту необходимо вызвать метод
lock(), который возвращаетstd::shared_ptr. Если исходный объект уже удалён,lock()вернёт пустойshared_ptr.if (auto shared_a = b->a_weak_ptr.lock()) { // Безопасная работа с shared_a } else { // Объект NodeA больше не существует } - Это стандартный паттерн для отношений "владелец-наблюдатель", где один объект владеет другим, а второй лишь наблюдает за первым, не продлевая его время жизни.