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

为何这段简单代码中的~TestClass()析构函数会被调用两次?

为什么这段C++代码的析构函数会被调用两次?

代码示例

#include <memory>
#include <iostream>
#include <vector>

class TestClass
{
  int m_val;

public:
  TestClass(int val);
  ~TestClass();
};

TestClass::TestClass(int val) : m_val(val)
{
  std::cout << this << " TestClass() " << m_val << "\n";
}

TestClass::~TestClass()
{
  std::cout << this << " ~TestClass() " << m_val << "\n";
  m_val = -1;
}

int main()
{
  auto x = std::make_unique<TestClass>(2);

  auto y = *x;  // <<<< this triggers it
}

运行输出

000001E66C0B5980 TestClass() 2
00000057FDD9FAB4 ~TestClass() 2   // why is the destructor called here?
000001E66C0B5980 ~TestClass() 2

原因解析

你看到两次析构是因为代码中实际创建了两个不同的TestClass对象:

  • 第一个对象是通过std::make_unique<TestClass>(2)在堆内存上创建的,地址为000001E66C0B5980。这个对象由智能指针x管理,当main函数结束时,智能指针生命周期终止,会自动销毁堆上的对象,触发最后一行的析构输出。
  • 第二个对象是执行auto y = *x;时生成的:*x返回智能指针指向的堆对象的引用,auto y = ...会调用编译器自动生成的默认拷贝构造函数,在栈内存上创建新的TestClass对象y(地址为00000057FDD9FAB4)。当main函数执行到末尾时,局部变量y的生命周期先结束,会被自动销毁,触发中间那行的析构输出。

简单来说:一次是栈上局部对象y的析构,一次是堆上智能指针管理对象的析构,因此总共触发两次析构调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 19:40:08