Понимание 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<<"\nFunc::a_ptr_ use_count = "<<bptr->a_ptr_.use_count();
std::cout<<"\nFunc::b_ptr_ use_count = "<<aptr->b_ptr_.use_count();
}

int main()
{
std::shared_ptr<A> aptr = std::make_shared<A>();
std::cout<<"\nBefore func::a_ptr_ use_count = "<<aptr.use_count();
func(aptr);
std::cout<<"\nAfter func::a_ptr_ use_count = "<<aptr.use_count();
std::cout<<"\nAfter 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

Однако я ожидал этого «После func :: a_ptr_ use_count = 1». После того, как bptr выходит из области видимости в func (), счетчик ссылок должен был уменьшиться.
Что мне здесь не хватает?

Вопрос, упомянутый как дубликат, не объясняет, как увеличивается / уменьшается счетчик ссылок. Меня больше интересует внутренняя механика того, как это делается (в shared_ptr), которая не объясняется в ответе на другой прилагаемый вопрос.

-1

Решение

Почему счетчик ссылок уменьшился? bptr может быть вне области, но bptr влияет только на количество ссылок для вашего B объект. Есть еще две ссылки на ваш A объект:

  1. Общий указатель все еще находится в области видимости в main
  2. Общий указатель хранится в вашем B объект

Пока есть живая ссылка на ваш A объект, ваш B объект продолжает существовать, и наоборот (это то, что вы умышленно вызвали, делая циклические общие ссылки). Сделать ваш B объект исчезнет, ​​вам понадобится одна ссылка в цикле ссылок, чтобы быть слабой / сырой, и очистить указатель, сохраненный в вашем main метод, поэтому ссылки верхнего уровня не сохраняются.

0

Другие решения

Других решений пока нет …