【发布时间】:2017-01-16 02:34:34
【问题描述】:
考虑以下概念/示例类
class Test
{
public:
explicit Test(std::string arg_string)
: my_string( std::move(arg_string) )
{ }
Test(const Test& Copy) {
this->my_string = Copy.my_string;
}
Test& operator=(Test Copy) {
MoveImpl( std::move(Copy) );
return *this;
}
Test(Test&& Moved) {
MoveImpl( std::forward<Test&&>(Moved) );
}
Test& operator=(Test&& Moved) {
MoveImpl( std::forward<Test&&>(Moved) );
return *this;
}
private:
void MoveImpl(Test&& MoveObj) {
this->my_string = std::move(MoveObj.my_string);
}
std::string my_string;
};
复制构造函数像往常一样采用const&。
复制赋值运算符是根据复制构造函数实现的(如果我没记错的话,Scott Meyers 指出异常安全和自赋值问题是通过这种方式解决的)。
在实现移动构造函数和移动赋值运算符时,我发现存在一些“代码重复”,我通过添加 MoveImpl(&&) 私有方法“消除”了这些。
我的问题是,由于我们知道复制赋值运算符获取了将在作用域结束时清理的对象的新副本,因此使用 MoveImpl() 函数来实现复制赋值运算符。
【问题讨论】:
-
这段代码真的有效吗?移动分配对我来说似乎是一个模棱两可的重载(例如在
Test() = Test();中)。 -
题外话:你为什么不在复制构造函数中使用成员初始化列表,或者为什么不只是
= default;呢?实际上,除了第一个构造函数之外,每个构造函数都进行了赋值,这不好。 -
std::forward<Test&&>(Moved)可以简单地为std::move(Moved)。 -
@KerrekSB,不,你是对的,确实代码抱怨重载解决方案。如果我将复制分配声明为
Test& operator=(const Test& Copy),错误就会消失。但是,我认为这会带来自分配和异常安全问题。 -
@LogicStuff,如果
MoveImpl执行移动,移动构造函数如何执行赋值?
标签: c++ c++11 move-semantics