为数组类实现移动构造函数(右值引用)

Implementing a move constructor(rvalue reference) for an array class

本文关键字:引用 构造函数 数组 实现 移动      更新时间:2023-10-16

我有一个数组类,我从一个网站上抓取了一个移动构造函数的例子。然而,如何在示例程序中实现这个move构造函数呢?我觉得我理解了函数的定义,但我不知道如何在程序中使用它。

class ArrayWrapper
{
public:
    // default constructor produces a moderately sized array
    ArrayWrapper ()
        : _p_vals( new int[ 64 ] )
        , _size( 64 )
    {}
    ArrayWrapper (int n)
        : _p_vals( new int[ n ] )
        , _size( n )
    {}
    // move constructor, how does this come in handy?
    ArrayWrapper (ArrayWrapper&& other)
        : _p_vals( other._p_vals  )
        , _size( other._size )
    {
        other._p_vals = NULL;
    }
    // copy constructor
    ArrayWrapper (const ArrayWrapper& other)
        : _p_vals( new int[ other._size  ] )
        , _size( other._size )
    {
        for ( int i = 0; i < _size; ++i )
        {
            _p_vals[ i ] = other._p_vals[ i ];
        }
    }
    ~ArrayWrapper ()
    {
        delete [] _p_vals;
    }
private:
    int *_p_vals;
    int _size;
};

如何在示例程序中实现这个移动构造函数呢?

我认为你的代码已经表明了这一点。

我觉得我理解了函数的定义,但是我不知道如何在程序中使用它。

只需使用几种触发移动的方法之一。例如:

ArrayWrapper aw;
ArrayWrapper aw2 = std::move(aw);

甚至:

ArrayWrapper foo()
{
    ArrayWrapper aw;
    //...
    return aw;
}
// ...
ArrayWrapper aw2 = foo();

请注意,在最后一种情况下,编译器可能会忽略对move构造函数的调用。

在与复制构造函数相同的情况下使用,但仅当被复制的表达式是右值时使用。右值通常指向一个临时对象。例如,如果您有一个函数foo,它按值返回ArrayWrapper,那么调用该函数的表达式将是一个右值。

ArrayWrapper aw = foo();

这里,ArrayWrapper对象将由foo返回的临时对象构造。选择move构造函数重载是因为右值引用实参绑定到右值表达式。

move构造函数通常会使要移动的对象处于有效但不确定的状态。