此问题在此处已有答案:
Destructor called unexpectedly(1个答案)
What is The Rule of Three?(8个回答)
7天前关闭
出于好奇:我在代码库中使用类型擦除,然后我注意到对象的析构函数被调用两次。
我用std::any简化了它,甚至用std::any,析构函数被调用两次:
https://godbolt.org/z/jaEqq7Psa的
struct foo
{
foo() {std::cout << "ctor\n"; }
~foo() {std::cout << "dtor\n"; }
};
int main()
{
std::any any_foo = foo{};
return 0;
}
字符串
我已经做了同样的例子,考虑到5的规则,有一个移动构造函数一旦被调用,我玩了一下,但我不能消除多个析构函数调用。
1条答案
按热度按时间dgsult0t1#
有一个移动构造函数,
这应该是一个明显的线索,表明您正在处理多个对象。
在格式良好和定义良好的代码中,每个构造的对象在某个时候都会被销毁。这是C的基础。
一个移动构造函数并没有改变这个规则。移动构造函数本身就是一个构造函数。所以它构造了一个对象。但是moved-from对象也必须在某个时候被构造。所以现在至少有两个对象在某个时候会被销毁。moved-from对象仍然是一个在某个时候被构造的C对象。所以它必须被销毁,在某些时候。即使在某些时候,它是moved-from,这也是真的。移动操作所做的就是让moved-from对象处于某种“有效,但未指定”的状态。它仍然是一个有效的对象。它会被销毁。
字符串
首先,一个临时的
foo
对象被创建。然后std::any
被构造,并吞下这个foo
。然而,std::any
不能通过渗透吸收其他对象。std::any
唯一能做的就是复制/移动它所拥有的另一个foo
。这就是你看到的移动构造函数被调用的地方。最后,临时的
foo
被销毁。然后,std::any
被销毁,它的析构函数也销毁了它拥有的foo
。这是第二个析构函数调用。在这里,
std::any
有它自己的对象,无论它是什么对象,它都拥有它。它不能接管已经构造的另一个对象的所有权。