C++移动构造函数

use*_*427 2 c++ move-semantics c++11

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

这是一个例子:

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?
                      );
};
Run Code Online (Sandbox Code Playgroud)

我在评论中显示了错误.

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

Ben*_*ley 11

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

Example(Example && rhs)
    :Number(rhs.Number)
    ,YesNo(rhs.YesNo)
    ,String(std::move(rhs.String))
    ,Vector(std::move(rhs.Vector))
{}
Run Code Online (Sandbox Code Playgroud)

你可以,如果你想,一致性,呼吁std::moveintbool,但你不会从中获得任何东西.

对于其他构造函数,使用所有参数,最简单的方法是:

Example(int p_Number, bool p_YesNo, std::string p_String)
    :Number(p_Number)
    ,YesNo(p_YesNo)
    ,String(std::move(p_String))
{}
Run Code Online (Sandbox Code Playgroud)

在回复您的评论如下:

每当您尝试构造一个具有与唯一构造函数参数相同类型的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
Run Code Online (Sandbox Code Playgroud)


Mik*_*our 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))
{}
Run Code Online (Sandbox Code Playgroud)

虽然,除非你的类本身是管理资源,否则完全没有必要写这个 - 隐式移动构造函数将完成与我编写的完全相同的东西.