You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何std::shared_ptr会两次调用TC对象的析构函数?

为什么会出现两次析构调用?

你的问题核心出在这行代码的写法上:

std::shared_ptr<TC> stc = std::make_shared<TC>(TC());

我们一步步拆解这行代码的执行流程,就能搞懂两次析构的来龙去脉:

  1. 生成临时对象:TC()会直接触发你写的默认构造函数,创建一个临时的TC实例——这就是你看到的TC Construct 0的来源,此时静态变量s_idx自增为1,这个临时对象的i_idx是0。
  2. 拷贝构造堆上实例:std::make_shared<TC>(...)会把刚才的临时对象作为参数,调用编译器自动生成的默认拷贝构造函数(你没显式定义,编译器会帮你生成一个),在堆上创建另一个TC实例。这个默认拷贝构造不会打印任何内容,所以你看不到第二个Construct输出,但这个堆上实例的i_idx同样是0(因为默认拷贝会复制成员变量的值)。
  3. 临时对象被销毁:当这行代码执行完毕,临时对象的生命周期结束,会立刻调用析构函数——这就是第一次TC Deconstruct 0的来源。
  4. shared_ptr管理的实例被销毁:当setup()函数执行完成,stc这个shared_ptr超出作用域,它会销毁自己管理的堆上TC实例,于是第二次调用析构函数,输出TC Deconstruct 0。

修复方案

你完全不需要给make_shared传递TC(),直接让make_shared帮你创建实例即可,这样只会生成一个对象:

std::shared_ptr<TC> stc = std::make_shared<TC>();

修改后执行,你会看到符合预期的输出:

Setup start
TC Construct 0
TC Deconstruct 0

只有当shared_ptr超出作用域时,才会调用一次析构函数。

内容的提问来源于stack exchange,提问作者hreintke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:42:13