移动构造函数并双删除

Gil*_* PJ 1 c++ move move-semantics c++11

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

#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()));
}
Run Code Online (Sandbox Code Playgroud)

Rak*_*111 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";
}
Run Code Online (Sandbox Code Playgroud)

你也可以使用std::swap(谢谢@RemyLebeau):

A(A&& t) : name("move"), data(nullptr)
{
    std::swap(data, t.data);
    cout << "i am move\n";
}
Run Code Online (Sandbox Code Playgroud)

  • 考虑使用`std :: swap()`代替:`A(A && t):name("move"),data(nullptr){std :: swap(data,t.data); cout <<"我动了\n"; }` (4认同)