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

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

我有一个实现了 move 语义的用户定义类(树结构)和一个 swap功能。我想实现一个 move以正确的方式运行,作为标准的 std::move 实现工作。

在树节点类中,每个子节点都有一个parent指针,指向父节点。这意味着对于 move 操作,所有 child 都必须重新设置父级(并且可能有很多 child )

这意味着使用 swap因为 move 不是最优的,因为两个列表的 child 在交换后必须重新设置。所以我想实现一个 move清除移出树的函数。

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

最佳答案

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

如果您编写了正确的 move 构造函数和 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;
}

程序的输出:

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

关于c++ - 如何为用户定义的类实现 c++11 move 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23604714/

相关文章:

c++ - 带有 cvfilter2d 的 opencv。我越来越黑了图片

c++ - 遍历基类成员

c++ - 为什么不能在派生类初始化时编译代码?

c++ - 构造函数中的初始化列表问题

c++ - 使用 g++ 在终端中运行 .cpp 文件时出错

c++ - 无法 move std::any

c++ - 在 Windows 中读取/写入各种音频文件元数据

c++ - `constexpr`和 `const`之间的区别

c++ - 继承后重新获得 move 可构造性

c++ - 为什么我可以使用删除的 move 构造函数和赋值运算符来 move 对象?