如何为用户定义的类实现c ++ 11移动函数?

gal*_*tte 2 c++ move move-semantics c++11

我有一个用户定义的类(树结构),带有实现的移动语义和一个swap函数.我想以move正确的方式实现一个函数,作为标准的std :: move实现.

在树节点类中,每个子节点都有一个parent指向父节点的指针.这意味着对于移动操作,所有儿童都必须进行重新设计(并且可能有很多孩子)

这意味着使用swap移动并不是最佳的,因为两个列表的子项在交换后都必须进行重新分配.所以我想实现一个move清除移动树的函数.

std :: move实现的声明有点复杂,它们使用std::remove_reference<T>::type&&返回类型.我需要这个吗?

Ric*_*ges 6

您不需要编写std :: move的特化.

如果你编写了一个正确的移动构造函数并移动赋值运算符,std :: move将适用于你的类.

例:

#include <iostream>
#include <cstring>

using namespace std;

struct Thing {
    Thing()
    : _data(new int[100])
    {
        cout << "default construct\n";

    }

    // Copy operator
    Thing(const Thing& other)
    : _data(new int[100])
    {
        cout << "copy constructor\n";
        memcpy(_data, other._data, sizeof(int) * 100);
    }

    // Move constructor
    Thing(Thing&& other) noexcept
    : _data(other._data)
    {
        cout << "move constructor\n";
        other._data = nullptr;
    }

    // assignment operator
    Thing& operator=(const Thing& rhs) {
        cout << "copy operator\n";
        if (&rhs != this) {
            Thing tmp(rhs);
            std::swap(*this, tmp);
        }
        return *this;
    }

    // move assignment operator
    Thing& operator=(Thing&& rhs) noexcept {
        cout << "move operator\n";
        std::swap(_data, rhs._data);
        return *this;
    }


    // destructor necessary since we are working in dangerous new/delete territory
    ~Thing() noexcept {
        cout << "destructor " << (_data ? "object has data" : "object is empty") << "\n";

        delete[] _data;
    }
private:
    int* _data;
};
int main()
{
    cout << "constructing a\n";
    Thing a;

    cout << "constructing b with copy of a\n";
    Thing b(a);

    cout << "moving a to newly constructed c\n";
    Thing c(std::move(a));

    cout << "moving c back to a\n";
    a = std::move(c);

    cout << "create a new d\n";
    Thing d;
    cout << "replace d with a copy of a\n";
    d = a;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

程序的输出:

constructing a
default construct
constructing b with copy of a
copy constructor
moving a to newly constructed c
move constructor
moving c back to a
move operator
create a new d
default construct
replace d with a copy of a
copy operator
copy constructor
move constructor
move operator
move operator
destructor object is empty
destructor object has data
destructor object has data
destructor object is empty
destructor object has data
destructor object has data
Run Code Online (Sandbox Code Playgroud)