C ++移动构造函数

时间:2013-03-02 00:32:10

标签: c++ c++11 move-semantics

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

以下是一个例子:

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

我在评论中显示了错误。

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

2 个答案:

答案 0 :(得分:11)

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

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

如果您愿意,可以保持一致性,在std::moveint上致电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值的情况是通过在L值上调用std::move。例如:

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

答案 1 :(得分:5)

移动构造函数将 rvalue 引用带到另一个相同类型的对象,并将其他对象的资源移动到新对象,例如:

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

虽然,除非你的类本身正在管理资源,否则完全没有意义 - 隐式移动构造函数将完成与我编写的完全相同的东西。