`std::shared_ptr` 循环依赖如何导致问题
How does `std::shared_ptr` cyclic dependency cause a problem
我发现了几个相关的问题,但找不到关于 "how" 这种情况的解释。
我有下面的代码,比可以创建循环shared_ptr
引用问题的版本落后一步。
(在 return 之前添加 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"
}
然而,事与愿违。 a
和 b
以相反的顺序被销毁。我看到以下输出。
Constructed a
Constructed b
Destructed a
Destructed b
上面的程序 returns 到底发生了什么?
(希望理解这个对理解循环依赖问题有所帮助)
析构函数主体在成员被销毁之前执行(与构造函数行为相反。)
因此当main
中的a
被析构时,a
的共享指针数先归零,然后析构managed Foo
被调用,first 打印消息 Destructed a
,然后 then other
被销毁,这导致 Destructed b
在其托管 Foo
.
的析构函数中打印
我发现了几个相关的问题,但找不到关于 "how" 这种情况的解释。
我有下面的代码,比可以创建循环shared_ptr
引用问题的版本落后一步。
(在 return 之前添加 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"
}
然而,事与愿违。 a
和 b
以相反的顺序被销毁。我看到以下输出。
Constructed a
Constructed b
Destructed a
Destructed b
上面的程序 returns 到底发生了什么? (希望理解这个对理解循环依赖问题有所帮助)
析构函数主体在成员被销毁之前执行(与构造函数行为相反。)
因此当main
中的a
被析构时,a
的共享指针数先归零,然后析构managed Foo
被调用,first 打印消息 Destructed a
,然后 then other
被销毁,这导致 Destructed b
在其托管 Foo
.