什么是正确的实现移动构造函数(和其他)

What is the correct implementation of move constructor (and others)?

本文关键字:构造函数 其他 移动 实现 什么      更新时间:2023-10-16

我有一个包含std::vector的简单类,我希望在按值返回类时受益于移动语义(不是RVO)。

我以以下方式实现了移动构造函数、复制构造函数和复制赋值操作符:

class A
{
    public:
        // MOVE-constructor.
        A(A&& other) :
            data(std::move(other.data))
        {
        }
        // COPY-constructor.
        A(const A& other) :
            data(other.data)
        {
        }
        // COPY-ASSIGNMENT operator.
        A& operator= (const A& other);
        {
            if(this != &other)
            {
                data = other.data;
            }
            return *this;
        }
    private:
        std::vector<int> data;
};

以上实现正确吗?

还有另一个问题:我是否需要实现这些成员,或者它们是由编译器自动生成的?我知道复制构造函数和复制赋值操作符是默认生成的,但是编译器也可以自动生成移动构造函数吗?(我用MSVC和GCC编译这段代码)

提前感谢任何建议。(我知道已经有一些类似的问题,但不是针对这个确切的场景。)

对于这个类[*]来说,它们都是不必要的,因为如果你没有声明它们,它就会有隐式的。

你的构造函数很好。下面的代码表面上调用move构造函数:

A f() { return A(); }
A a = f(); // move construct (not copy construct) from the return value of f

实际上可能会触发move-省略,在这种情况下,实际上只调用无参数的构造函数。我假设您计划提供一些构造函数,而不是复制和移动;-)

你的拷贝赋值很好,它与隐式赋值的区别只是在于它有自赋值检查,而隐式赋值没有。我认为我们不应该争论自赋值检查是否值得,这并不是不正确的。

没有定义移动赋值操作符。如果你定义了其他的,你应该这样做,但是如果你去掉了其余的,它就是隐式的[*]。move赋值操作符(无论是用户定义的还是隐式的)确保以下代码将移动而不是复制:

A a;
a = f();

[*]在一个已完成的c++ 11实现上,到目前为止还不存在。您可以在每个编译器的基础上检查此功能是否已经实现,并且可能在MSVC实现之前,您将以一些可怕的#define恶作剧告终。

对于这个确切的场景,您不需要声明任何移动/复制/赋值函数。编译器会生成正确的默认值

相关文章: