例如,以下移动构造函数在没有&&
(右值引用)的情况下工作:
Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {
obj.elem = nullptr;
obj.data = 0;
}
我真的不明白为什么它是必要的......
例如,以下移动构造函数在没有&&
(右值引用)的情况下工作:
Obj::Obj(Obj& obj) : elem { obj.elem }, data(obj.data) {
obj.elem = nullptr;
obj.data = 0;
}
我真的不明白为什么它是必要的......
右值引用参数将拒绝绑定到非右值引用。由于这个限制,move
只有当被移动的对象以后永远不能在代码中显式引用时(因为它是一个临时被丢弃,或者返回一个局部变量),或者因为调用者显式地move
d从他们。
要了解为什么需要这样做,您可以查看 的历史记录auto_ptr
,或者您可以阅读此示例,该示例使用您的Obj
类型:
int main() {
Obj a;
Obj b = a; // oops! You just *moved* a into b!
}
使用适当的move
构造函数,仅当右侧是以编译器可以检测到的方式立即丢弃的值或您调用move
.
最重要的是,&
引用拒绝绑定到临时对象——临时对象只能绑定到 aconst&
或 a &&
。
你的例子不能绑定到一个临时的,所以这些不起作用:
Obj makeObj() { return Obj(); }
Obj o1(Obj()); // Error
Obj o2(makeObj()); // Error
此外,它使破坏事情变得非常容易,因为您本质上有一个复制构造函数,可以从它正在复制的对象中窃取状态:
Obj o1;
Obj o2{o1}; // o1 is modified