为什么移动构造函数需要使用"右值引用"?

Ole*_*siy 2 c++ constructor move-constructor c++11

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

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

Yak*_*ont 14

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

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

int main() {
  Obj a;
  Obj b = a; // oops!  You just *moved* a into b!
}
Run Code Online (Sandbox Code Playgroud)

使用适当的move构造函数,只有当右侧是一个将以编译器可以检测到或调用的方式立即丢弃的值时,才会调用它move.

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


jua*_*nza 12

您的示例无法绑定到临时,因此这些不起作用:

Obj makeObj() { return Obj(); }

Obj o1(Obj());     // Error
Obj o2(makeObj()); // Error
Run Code Online (Sandbox Code Playgroud)

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

Obj o1;
Obj o2{o1}; // o1 is modified
Run Code Online (Sandbox Code Playgroud)