【问题标题】:Why does a move constructor need to use "rvalue reference"?为什么移动构造函数需要使用“右值引用”?
【发布时间】:2013-08-11 11:00:46
【问题描述】:

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

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

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

}

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

【问题讨论】:

  • 那不是移动构造函数。那是一个复制构造函数,那也是一个坏的。
  • 它是一个拷贝构造函数。好吧,Nawaz 更快:P。

标签: c++ c++11 constructor move-constructor


【解决方案1】:

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

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

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

使用正确的 move 构造函数,它仅在右侧是一个将立即以编译器可以检测到的方式丢弃的值时调用,或者您调用 move。

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

【讨论】:

    【解决方案2】:

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

    Obj makeObj() { return Obj(); }
    
    Obj o1(Obj());     // Error
    Obj o2(makeObj()); // Error
    

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

    Obj o1;
    Obj o2{o1}; // o1 is modified
    

    【讨论】:

    • 呸,忘了提这个。公然窃取你的答案!
    • 我看到你回报了。 ;)
    • @Yakk 看起来可能是这样,但我打字太忙了,没有注意到任何东西 :)
    • 因为我不知道谁抄袭了谁,所以我给你们两个投了赞成票
    • @JoshG79 我忘了在我的回答中包含“哦,它不适用于临时人员”部分,这是 juan 开始的。 (我意识到我忘记了那部分后,我编辑的答案的最后一段!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 1970-01-01
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 2017-01-10
    • 1970-01-01
    相关资源
    最近更新 更多