我对使用 C++0x 移动语义移动对象后的状态感到困惑。我的理解是,一旦一个对象被移动,它仍然是一个有效的对象,但是它的内部状态已经改变了,所以当它的析构函数被调用时,没有资源被释放。
但是如果我的理解是正确的,移动对象的析构函数仍然应该被调用。
但是,当我执行一个简单的测试时,这不会发生:
struct Foo
{
Foo()
{
s = new char[100];
cout << "Constructor called!" << endl;
}
Foo(Foo&& f)
{
s = f.s;
f.s = 0;
}
~Foo()
{
cout << "Destructor called!" << endl;
delete[] s; // okay if s is NULL
}
void dosomething() { cout << "Doing something..." << endl; }
char* s;
};
void work(Foo&& f2)
{
f2.dosomething();
}
int main()
{
Foo f1;
work(std::move(f1));
}
这个输出:
Constructor called!
Doing something...
Destructor called!
注意析构函数只被调用一次。这表明我在这里的理解是错误的。为什么没有调用两次析构函数?这是我对应该发生的事情的解释:
Foo f1
被构造。Foo f1
被传递给work
,它接受一个 rvaluef2
。Foo
调用移动构造函数,将所有资源移动f1
到f2
.- Now
f2
的析构函数被调用,释放所有资源。 - Now
f1
的析构函数被调用,它实际上并没有做任何事情,因为所有资源都被转移到了f2
. 尽管如此,还是调用了析构函数。
但是由于只调用了一个析构函数,因此第 4 步或第 5 步都不会发生。我从析构函数进行了回溯,以查看它是从哪里调用的,并且它是从第 5 步调用的。那么为什么不调用f2
' 析构函数呢?
编辑:好的,我修改了这个,所以它实际上是在管理一个资源。(一个内部内存缓冲区。)不过,我得到了与只调用一次析构函数相同的行为。