首页 > 解决方案 > 我的移动构造函数和移动赋值运算符写得好吗?

问题描述

我在这个结构中添加移动构造函数和移动赋值运算符。谁能告诉我他们写得好不好?当我在没有这两种方法的情况下运行代码时,一切正常,但是当我添加这两种方法时,它不起作用。非常感谢

    struct Data {
        Data() = default;
    
        Data(const unsigned int _x) : data(new unsigned char[_x]), size(_x) {}
    
        Data(const Data &_d) : data(new unsigned char[_d.size]), size(_d.size) {
            memcpy(data, _d.data, _d.size);
        }
    
        ~Data() {
            delete[] data;
            size = 0;
        };
    
        Data& operator=(const Data &_d) {
            if (this == &_d) {
                return *this;
            }
            unsigned char *tmp(new unsigned char[_d.size]);
            memcpy(tmp, _d.data, _d.size);
            delete[] data;
            data = tmp;
            size = _d.size;
            return *this;
        }
    

这是我的移动构造函数,我应该首先删除数据,如果大小不相等,则分配新大小的数据?

Data(Data &&_d)
    {
        data = _d.data;
        _d.data = nullptr;
        size = _d.size;
        _d.size = 0;
    }

这是我的移动赋值运算符

    Data& operator=(Data&& _d)
    {
        if (this != &_d)
        {
            delete[] data;
            data = _d.data;
            _d.data = nullptr;
            size = _d.size;
            _d.size = 0;
        }
        return *this;
    }
    
        unsigned char *data = nullptr;
        unsigned int size = 0;
    };

标签: c++constructoroperatorsc++17dynamic-memory-allocation

解决方案


你的代码是正确的。

但也有一种使用std::swap实现移动分配的模式:

Data& operator=(Data&& _d)
{
    std::swap(data, _d.data);
    std::swap(s, _d.size);
    return *this;
}

_d在这里,当调用析构函数时,旧数据将被释放。

这不是一个“更正确的方法”,但它更容易编写并且留下更少的空间来忘记正确处置资源。

移动构造函数可以重用移动赋值:

Data(Data&& _d)
    : this() 
{
    *this = std::move(_d);
}

同样,这不是更好的方法,但可以减少重复代码的数量。


推荐阅读