How to break shared_ptr cyclic reference using weak_ptr

丶灬走出姿态 提交于 2019-11-28 06:31:48

The classic example of cyclic references is where you have two classes A and B where A has a reference to B which has a reference to 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";
}

If both references are shared_ptr then that says A has ownership of B and B has ownership of A, which should ring alarm bells. In other words, A keeps B alive and B keeps A alive.

In this example the instances a and b are only used in the useAnB() function so we would like them to be destroyed when the function ends but as we can see when we run the program the destructors are not called.

The solution is to decide who owns who. Lets say A owns B but B does not own A then we replace the reference to A in B with a weak_ptr like so:

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

Then if we run the program we see that a and b are destroyed as we expect.

Live demo

Edit: In your case, the approach you suggested looks perfectly valid. Take ownership away from A and something else owns the As.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!