0

I have an array class I grabbed off of a website that gives an example of a move constructor. How would one implement this move constructor in an example program however? I feel like I understand the function definition, but I have no idea how one would make use of this in a program.

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;
};
Syntactic Fructose
  • 18,936
  • 23
  • 91
  • 177
  • 1
    [What are move semantics](http://stackoverflow.com/questions/3106110/what-are-move-semantics) – David G May 13 '13 at 23:48

2 Answers2

2

How would one implement this move constructor in an example program however?

I think the code you have shows that already.

I feel like I understand the function definition, but I have no idea how one would make use of this in a program.

Just use one of the several ways to trigger a move. For instance:

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

Or even:

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

// ...

ArrayWrapper aw2 = foo();

Notice, that in this last case the compiler is likely to elide the call to the move constructor anyway.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
1

It is used in the same situations that the copy constructor would be but only if the expression being copied from is an rvalue. An rvalue typically refers to a temporary object. So, for example, if you have a function foo that returns an ArrayWrapper by value, the expression that calls that function would be an rvalue.

ArrayWrapper aw = foo();

Here, the ArrayWrapper object will be constructed from the temporary object returned by foo. The move constructor overload is chosen because the rvalue reference argument binds to the rvalue expression.

A move constructor typically leaves the object it is moving from in an valid but indeterminate state.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324