移动构造函数并双重删除
Move constructor and double delete
最初我以为移动构造函数不会调用临时对象的析构函数但是当我尝试时它正在调用析构函数。因此,当我们从移动构造函数窃取数据时,出现双重删除错误。
#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()));
}
那是因为你实际上并不是 "stealing",你只是在复制,所以你会删除 2 次相同的指针,正如你所注意到的。
要实际 "steal" 数据,请将原始数据设置为 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";
}
最初我以为移动构造函数不会调用临时对象的析构函数但是当我尝试时它正在调用析构函数。因此,当我们从移动构造函数窃取数据时,出现双重删除错误。
#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()));
}
那是因为你实际上并不是 "stealing",你只是在复制,所以你会删除 2 次相同的指针,正如你所注意到的。
要实际 "steal" 数据,请将原始数据设置为 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";
}