我试图了解什么似乎是一个怪异的行为时分配一个新的值分配到堆栈上的对象(析构函数被调用两次相同的数据集)。我就开始与代码片段,其输出:C++堆栈分配的对象分配和析构函数调用
class Foo {
public:
Foo(const string& name) : m_name(name) {
log("constructor");
}
~Foo() {
log("destructor");
}
void hello() {
log("hello");
}
private:
string m_name;
void log(const string& msg) {
cout << "Foo." << this << " [" << m_name << "] " << msg << endl;
}
};
int main() {
{
Foo f {"f1"};
f.hello();
f = Foo {"f2"};
f.hello();
}
cout << "scope end" << endl;
}
输出:
Foo.0x7fff58c66a58 [f1] constructor
Foo.0x7fff58c66a58 [f1] hello
Foo.0x7fff58c66a18 [f2] constructor
Foo.0x7fff58c66a18 [f2] destructor
Foo.0x7fff58c66a58 [f2] hello
Foo.0x7fff58c66a58 [f2] destructor
scope end
我希望发生:
- 0X ...... 58被创建/初始化在堆栈上
- 0x ... 18在堆栈上创建/初始化
- Foo析构函数在0x ... 58上调用F1数据)
- 富析构函数被调用于0X ... 18(具有f数据)
居然会发生什么:
- 0X ...... 58时生成/初始化堆栈
- 0X ... 18获取创建/初始化堆栈上从0X ... 18(F2)
- 数据被复制到0X ... 58
- 富析构函数被调用于0X ... 18(具有f数据)
- 富析构函数被调用的0X ... 58(也具有f数据)
所以在最后,Foo析构函数被两次调用相同的数据(f2)。很明显,我错过了一些关于内部工作原理的东西,所以有人可以请我指出正确的方向吗?
因为您已经复制了一个临时对象,它将'f'所保持的名称从''f1''更改为''f2''',所以不会看到“f1”'析构函数的消息。因此,你首先会看到临时的“f2”破坏,然后原始实例(现在称为“f2”)被破坏。请注意,数据不一样;它是具有相同值的副本。 –
如果你的类有一个析构函数,它应该几乎肯定也有一个拷贝构造函数和赋值运算符。 –
并且(可能)移动构造函数和移动赋值操作符(“五个规则”)。 –