2

使用或创建移动构造函数的正确方法是什么?

这是一个例子:

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?
                      );
};

我已经在评论中显示了错误。

编辑: *好的,我现在确定我所拥有的不是移动构造函数。那么,我可以写一个吗?*

4

2 回答 2

11

首先,没有理由为该类编写移动构造函数。编译器生成的就可以了。但如果你要写它,它可能看起来像这样:

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

如果您愿意,为了保持一致性,您可以调用std::movetheint和 the bool,但您不会从中获得任何收益。

对于具有所有参数的其他构造函数,最简单的做法是:

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

针对您的以下评论:

每当您尝试使用与唯一构造函数参数相同类型的 R 值构造对象时,都会调用移动构造函数。例如,当一个对象通过函数的值返回时,即 R 值,尽管在这种情况下,通常会完全跳过复制和移动。您可以创建 R 值的一种情况是调用std::moveL 值。例如:

Example ex1(7, true, "Cheese"); // ex1 is an L-value
Example ex2(std::move(ex1));    // moves constructs ex2 with ex1
于 2013-03-02T00:44:40.227 回答
5

移动构造函数接受对另一个相同类型对象的右值引用,并将另一个对象的资源移动到新对象,例如:

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))
{}

虽然,除非你的类本身在管理资源,否则写这个完全没有意义——隐式移动构造函数将做与我写的完全相同的事情。

于 2013-03-02T00:45:41.597 回答