我找到了几个相关的问题,但是找不到关于“如何”发生的解释。
我有以下代码,比可以创建循环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"
}
但是,事情没有发生我所期望的。 a
和b
的破坏顺序相反。我看到以下输出。
Constructed a
Constructed b
Destructed a
Destructed b
当程序返回到上面时,究竟发生了什么? (我希望了解这一点有助于理解周期性依赖问题)
答案 0 :(得分:4)
析构函数主体在成员被销毁之前被执行(与构造函数行为相反)。
因此,当a
中的main
被销毁时,a
的共享指针计数首先达到零, ,然后是托管的{{1} }被调用, first 首先放置消息Foo
,然后 then Destructed a
被销毁,这导致other
被打印在托管Destructed b
的析构函数。