为何这段简单代码中的~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
相关产品推荐
相关产品推荐

