了解具有循环引用的SHARED_PTR?

2022-07-20 00:00:00 cyclic-reference c++ c++11 shared-ptr

我想了解SHARED_PTR如何递增或递减引用计数?

 #include <iostream>
 #include <memory>

class B;

class A
{
  public:
  std::shared_ptr<B> b_ptr_;
};

class B
{
  public: 
  std::shared_ptr<A> a_ptr_;
};

void func(std::shared_ptr<A> &aptr)
{
  std::shared_ptr<B> bptr = std::make_shared<B>(); //Creating shared pointer
  bptr->a_ptr_ = aptr; // Creating cyclic dependency 
  aptr->b_ptr_ = bptr;

  std::cout<<"
Func::a_ptr_ use_count = "<<bptr->a_ptr_.use_count();
  std::cout<<"
Func::b_ptr_ use_count = "<<aptr->b_ptr_.use_count();     
}

int main()
{
  std::shared_ptr<A> aptr = std::make_shared<A>();
  std::cout<<"
Before func::a_ptr_ use_count = "<<aptr.use_count();
  func(aptr);
  std::cout<<"
After func::a_ptr_ use_count = "<<aptr.use_count();
  std::cout<<"
After func::b_ptr_ use_count = "<<aptr->b_ptr_.use_count();
  return 0;   
}

Output: 
This is the output I see:
Before func::a_ptr_ use_count = 1
Func::a_ptr_ use_count = 2
Func::b_ptr_ use_count = 2
After func::a_ptr_ use_count = 2
After func::b_ptr_ use_count = 1
然而,我预料到这是"After Func::A_PTR_USE_COUNT=1"。在bptr超出func()的作用域之后,引用计数应该会递减。 我在这里错过了什么?

提到的重复问题没有解释如何递增/递减引用计数。我更感兴趣的是如何做到这一点的内部机制(在Shared_ptr中),这在附加的另一个问题的答案中没有解释。


解决方案

为什么应该减少引用计数?bptr可能超出范围,但bptr只影响B对象的引用计数。仍然有两个对A对象的引用:

  1. 共享指针仍在main中的作用域
  2. B对象中存储的共享指针
只要存在对A对象的活动引用,B对象就会继续存在,反之亦然(这是您通过循环共享引用故意触发的)。若要使B对象消失,您需要在引用循环中有一个引用是弱/原始的,并清除main方法中存储的指针,这样顶级引用就不会持续存在。

相关文章