Как разорвать циклическую ссылку shared_ptr с помощью weak_ptr

Я читал, что уязвимые_поинтеры могут использоваться для разрыва циклических ссылок

Рассмотрим следующий пример циклической ссылки

struct A
{
boost::shared_ptr<A> shrd_ptr;
};


boost::shared_ptr<A> ptr_A(boost::make_shared<A>());
boost::shared_ptr<A> ptr_b(boost::make_shared<A>());
ptr_A->shrd_ptr = ptr_b;
ptr_b->shrd_ptr = ptr_A;

Теперь выше приведен случай циклической ссылки, и я хотел знать, как можно разорвать циклическую ссылку выше с помощью weak_ptr?

Обновление: на основании полученного предложения я придумал следующее:

struct A
{
  boost::weak_ptr<A> wk_ptr;
};

    boost::shared_ptr<A> ptr_A (boost::make_shared<A>());
    boost::shared_ptr<A> ptr_B (boost::make_shared<A>());
    ptr_A->wk_ptr = ptr_B;
    ptr_B->wk_ptr = ptr_A;

Будет ли это правильный подход?

1 ответ

Решение

Классический пример циклических ссылок, где у вас есть два класса A а также B где A имеет ссылку на B который имеет ссылку на A:

#include <memory>
#include <iostream>

struct B;
struct A {
  std::shared_ptr<B> b;  
  ~A() { std::cout << "~A()\n"; }
};

struct B {
  std::shared_ptr<A> a;
  ~B() { std::cout << "~B()\n"; }  
};

void useAnB() {
  auto a = std::make_shared<A>();
  auto b = std::make_shared<B>();
  a->b = b;
  b->a = a;
}

int main() {
   useAnB();
   std::cout << "Finished using A and B\n";
}

Если обе ссылки shared_ptr тогда это говорит A владеет B а также B владеет A, который должен звонить в колокола. Другими словами, A держит B жив и B держит A в живых.

В этом примере экземпляры a а также b используются только в useAnB() функция, поэтому мы хотели бы, чтобы они были уничтожены, когда функция заканчивается, но, как мы видим, когда мы запускаем программу, деструкторы не вызываются.

Решение состоит в том, чтобы решить, кто кому принадлежит. Допустим A владеет B но B не владеет A тогда мы заменим ссылку на A в B с weak_ptr вот так:

struct B {
  std::weak_ptr<A> a;
  ~B() { std::cout << "~B()\n"; }  
};

Тогда, если мы запустим программу, мы увидим, что a а также b уничтожены, как мы ожидаем.

Живая демо

Редактировать: в вашем случае предложенный вами подход выглядит вполне обоснованным. Отнимите собственность от A и что-то еще владеет As.

Другие вопросы по тегам