移动构造函数并双重删除

时间:2016-07-07 18:40:38

标签: c++ c++11 move move-semantics

最初我认为移动构造函数不会调用临时对象析构函数,但是当我尝试它时调用析构函数。所以当我们从移动构造函数中窃取数据时,我得到双删除错误。

#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()));
}

1 个答案:

答案 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";
}