2

例如,以下移动构造函数在没有&&(右值引用)的情况下工作:

Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {

    obj.elem = nullptr;
    obj.data = 0;

}

我真的不明白为什么它是必要的......

4

2 回答 2

14

右值引用参数将拒绝绑定到非右值引用。由于这个限制,move只有当被移动的对象以后永远不能在代码中显式引用时(因为它是一个临时被丢弃,或者返回一个局部变量),或者因为调用者显式地moved从他们。

要了解为什么需要这样做,您可以查看 的历史记录auto_ptr,或者您可以阅读此示例,该示例使用您的Obj类型:

int main() {
  Obj a;
  Obj b = a; // oops!  You just *moved* a into b!
}

使用适当的move构造函数,仅当右侧是以编译器可以检测到的方式立即丢弃的值或您调用move.

最重要的是,&引用拒绝绑定到临时对象——临时对象只能绑定到 aconst&或 a &&

于 2013-08-09T13:38:46.563 回答
12

你的例子不能绑定到一个临时的,所以这些不起作用:

Obj makeObj() { return Obj(); }

Obj o1(Obj());     // Error
Obj o2(makeObj()); // Error

此外,它使破坏事情变得非常容易,因为您本质上有一个复制构造函数,可以从它正在复制的对象中窃取状态:

Obj o1;
Obj o2{o1}; // o1 is modified
于 2013-08-09T13:38:29.057 回答