最初我认为移动构造函数不会调用临时对象析构函数,但是当我尝试它时调用析构函数。所以当我们从移动构造函数中窃取数据时,我得到双删除错误。
#include <iostream>
using namespace std;
class A
{
public:
A()
: name("default")
{
cout<<"i am default\n";
data = new char[20];
}
A(A&& t)
: name("move")
{
data = t.data;
cout<<"i am move\n";
}
~A()
{
delete data;
cout<<"I am done:"<<name<<endl;
}
char * data;
string name;
};
A getA()
{
A obj;
return obj;
}
int main()
{
A test(std::move(getA()));
}
答案 0 :(得分:11)
那是因为你实际上并没有“偷”,你只是在复制,所以你会删除相同指针的2倍,就像你注意到的那样。
要实际“窃取”数据,请将原始数据设置为nullptr
,因为它不再属于该对象。
A(A&& t)
: name("move")
{
data = t.data;
t.data = nullptr; //'t' doesn't own its data anymore
cout<<"i am move\n";
}
您也可以使用std::swap
(感谢@RemyLebeau):
A(A&& t) : name("move"), data(nullptr)
{
std::swap(data, t.data);
cout << "i am move\n";
}