使用或创建移动构造函数的正确方法是什么?
以下是一个例子:
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?
);
};
我在评论中显示了错误。
修改 * 好的,我现在确定我拥有的不是移动构造函数。那么,我可以写一个吗? *
答案 0 :(得分:11)
首先,没有理由为该类编写移动构造函数。生成的编译器就可以了。但如果你要写它,它可能看起来像这样:
Example(Example && rhs)
:Number(rhs.Number)
,YesNo(rhs.YesNo)
,String(std::move(rhs.String))
,Vector(std::move(rhs.Vector))
{}
如果您愿意,可以保持一致性,在std::move
和int
上致电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))
{}
虽然,除非你的类本身正在管理资源,否则完全没有意义 - 隐式移动构造函数将完成与我编写的完全相同的东西。