"std::shared_ptr"循环依赖关系是如何导致问题的

How does `std::shared_ptr` cyclic dependency cause a problem

本文关键字:quot 何导致 关系 问题 ptr std shared 循环 依赖      更新时间:2023-10-16

我发现了几个相关的问题,但我找不到关于"如何"发生这种情况的解释。

我有以下代码,它比可以创建循环shared_ptr引用问题的版本落后一步。(返回前添加b.other = a;导致问题(

为了更好地澄清,我在重要的行上添加了注释,以表明当时程序的状态。

#include <iostream>
#include <memory>
using namespace std;
struct Foo
{
explicit Foo(char i) : id{i} { cout << "Constructed " << id << endl; }
~Foo() { cout << "Destructed " << id << endl; }
shared_ptr<Foo> other = {};
char const id;
};
int main()
{
auto const a = make_shared<Foo>('a'); // a_use_count = 1, b_use_count = 0
auto const b = make_shared<Foo>('b'); // a_use_count = 1, b_use_count = 1
a->other = b; // a_use_count = 1, b_use_count = 2
return 0;     // What happens now? Following is my "expectation" (which is wrong !)
// 1. destruct b => a_use_count = 1, b_use_count = 1
// 2. destruct a (in following order)
//    2.1 destruct a.other => b_use_count = 0 => show "Destructed b"
//    2.2 destruct a       => a_use_count = 0 => show "Destructed a"
}

然而,事情并没有像我预期的那样发生。CCD_ 3和CCD_。我看到以下输出。

Constructed a
Constructed b
Destructed a
Destructed b

当程序返回到上面时,会发生什么?(我希望理解这一点将有助于理解循环依赖性问题(

析构函数主体在成员被销毁之前执行(构造函数行为的相反(

因此,当main中的a被销毁时,a的共享指针计数首先达到零,然后调用托管Foo的销毁器,首先生成消息Destructed a,然后销毁other,这导致Destructed b被打印在其托管Foo的销毁器中。