user2117427
user2117427

Reputation: 487

C++ Move Constructor

What is the correct way of using or creating a move constructor?

Here is an example:

class Example
{
public:
    Example( int && p_Number,
             bool && p_YesNo,
             std::string && p_String ) : // Error here
             Number( p_Number ),
             YesNo( p_YesNo ),
             String( p_String )
    {
    };

private:
    int Number;
    bool YesNo;
    std::string String;
    std::vector< unsigned char > Vector;
};

void ShowExample( void )
{
    Example ExampleA( 2013,
                      true,
                      "HelloWorld" // Why won't it work?
                      );
};

I've shown the errors in the comment.

Edit: *Okay, I am now sure what I have is not a move constructor. So, can I write one?*

Upvotes: 2

Views: 3007

Answers (2)

Benjamin Lindley
Benjamin Lindley

Reputation: 103751

First of all, there is no reason to write a move constructor for that class. The compiler generated one will do just fine. But if you were to write it, it might look something like this:

Example(Example && rhs)
    :Number(rhs.Number)
    ,YesNo(rhs.YesNo)
    ,String(std::move(rhs.String))
    ,Vector(std::move(rhs.Vector))
{}

You can, if you want, for consistency, call std::move on the int and the bool, but you won't gain anything from it.

For that other constructor, with all the arguments, the simplest thing to do is this:

Example(int p_Number, bool p_YesNo, std::string p_String)
    :Number(p_Number)
    ,YesNo(p_YesNo)
    ,String(std::move(p_String))
{}

In response to your comment below:

A move constructor is invoked whenever you try to construct an object with an R-value of the same type as the only constructor argument. For example, when an object is returned by value from a function, that is an R-value, although often in that case, copying and moving is skipped altogether. A case where you can create an R-value is by calling std::move on an L-value. For example:

Example ex1(7, true, "Cheese"); // ex1 is an L-value
Example ex2(std::move(ex1));    // moves constructs ex2 with ex1

Upvotes: 11

Mike Seymour
Mike Seymour

Reputation: 254751

A move constructor takes an rvalue reference to another object of the same type, and moves the other object's resources to the new object, for example:

Example(Example && other) :
    Number(other.Number),             // no point in moving primitive types
    YesNo(other.YesNo),
    String(std::move(other.String)),  // move allocated memory etc. from complex types
    Vector(std::move(other.Vector))
{}

Although, unless your class is itself managing resources, there's no point in writing this at all - the implicit move constructor will do exactly the same thing as the one I wrote.

Upvotes: 5

Related Questions