提问人:Jabberwocky 提问时间:11/10/2023 更新时间:11/10/2023 访问量:130
析构函数意外调用
Destructor called unexpectedly
问:
为什么这个简单代码中的析构函数被调用了两次?~TestClass()
#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
答:
1赞
user12002570
11/10/2023
#1
auto y = *x;
<<<<这会触发它
以上是复制初始化,将使用类的复制构造函数。您看到的额外析构函数调用对应于此对象。您还可以通过向类中添加复制 ctor 来验证这一点,您会注意到该复制 ctor 用于使用 .y
y
*x
class TestClass
{
int m_val;
public:
TestClass(int val);
~TestClass();
//added this copy ctor
TestClass(const TestClass &p): m_val(p.m_val)
//-------------------------------^^^^^^^^^^^^^^--->use member initializer list
{
std::cout << this << " copy ctor " << m_val << "\n";
}
};
//other code as before
评论
0赞
Red.Wave
11/11/2023
TestClass z {3}; z=y;
和繁荣。你又失败了。 永远不会被破坏。3
0赞
user12002570
11/11/2023
@Red.Wave 问题不在于任何违规行为。这是关于为什么没有 dtor 调用。代码中的任何逻辑错误都不是我的责任来解决的。
0赞
Red.Wave
11/11/2023
很明显,您也需要学习 RAII。您的解决方案违反了规则 0/3/5;简而言之,这是错误的。答案应该提供关于问题根源的足够信息,而你的答案却没有。因为你自己不知道真正的问题。讨论结束。
0赞
user12002570
11/11/2023
@Red.Wave:不,解决世界上所有的问题或别人的代码不是我的责任。他们对自己的代码负全部责任。我不为别人的错误负责。我只指出问题中具体提出的问题,这就是为什么没有 dtor 调用。你不能把你的错误归咎于我。您最多可以建议链接到 OP 的三法则。
0赞
Red.Wave
11/11/2023
您有责任不传播错误信息,而是提及正确答案。你当然不能提到你还没有掌握的东西;那是有人纠正你的时候。
上一个:如何在C#中排排对象列表?
下一个:尝试添加带有附加智能指针的矢量
评论
make_unique
y
auto y = *x;
y
是 so then 被销毁并紧随其后的副本。*x
y
*x
TestClass