zoukankan      html  css  js  c++  java
  • 右值引用深入探讨

    假若X这个类型重载了拷贝构造以及移动构造。

    那么思考一下:

    void foo(X&& x)
    {
      X anotherX = x;
      // ...
    }

    哪个构造函数将会被调用?在这里x是右值引用类型,那么他是右值还是左值呢?之前对左值和右值的定义中已经表明了,如果我们可以对其进行取址操作,那么他就是左值,

    所以你可以对右值引用进行取址操作吗?

    于是,右值引用的设计者这样说:

    “右值引用变量既可以是右值也可以是左值,这取决于:如果他有名字,那么他是左值,否则,为右值”。

    所以在上面的例子中,x是有名字的,所以他是左值!所以调用的是拷贝构造函数。

    接着看下面这个例子:

    X&& goo();
    X x = goo(); // 调用 X(X&& rhs) 因为goo()的返回值没有名字。
    

    其实这样也很容易理解,当右值引用有名字的时候,这代表这个变量有可能在其他地方被引用到,那么一旦被看作是右值,那么就危险了,因为右值的意思是,这个值是无所谓的,或者说这个值里面的内容我们不关心,所以我们才会对他进行swap操作,或者其他对其有副作用的操作,因为反正右值里面的东西是“垃圾堆”,我们忘里面扔就好了,但是如果他会被其他人引用到,那么这个垃圾堆就会产生危害。而当右值引用没名字的时候,我们也无法对他进行引用,所以我们可以大胆放心的把他当作右值进行使用。

    看下面一个例子:

    Base(Base const & rhs); // non-move semantics
    Base(Base&& rhs); // move semantics

    那么他的子类Derived应该如何实现呢?

    Derived(Derived const & rhs) 
      : Base(rhs)
    {
      // Derived-specific stuff
    }

    这样写很正常,没什么问题,注意:会有一个类型转换在里面。

    那move constructor怎么写?

    Derived(Derived&& rhs) 
      : Base(rhs) // wrong: rhs is an lvalue
    {
      // Derived-specific stuff
    }

    当然,我们想调用的是Base的move构造,但是这里参数rhs是有名字的,所以我们调用错了,这里就可以使用std::move来进行转换一下。

    Derived(Derived&& rhs) 
      : Base(std::move(rhs)) // good, calls Base(Base&& rhs)
    {
      // Derived-specific stuff
    }

     接下来,看下面的代码:

    X foo()
    {
      X x;
      // perhaps do something to x
      return x;
    }

    同样,X重载了拷贝构造以及移动构造。

    这时候你的小聪明作祟,心想,这样不是拷贝了好几次嘛,于是你把代码改成这样:

    X foo()
    {
      X x;
      // perhaps do something to x
      return std::move(x); // making it worse!
    }

    不幸的是,这样反倒使得效率更低。我们都知道现代的编译器会进行一些优化,在不影响代码逻辑的前提下。

    那么我相信大家一定听说过返回值优化这个东西,所以如果你使用第一种返回方式,那么X的构造可能只有一次,而第二种小聪明的返回方式会调用默认构造+移动构造,反而效率更低。所以为了更好的使用移动语义,你需要对编译器优化进行一定的了解,否则有可能画蛇添足。

  • 相关阅读:
    微信公众平台可通过UnionID机制在多公众号间帐号互通
    草根玩微博 中产玩微信 土豪玩什么?支持Yo的iWatch?
    The Model Complexity Myth
    BuzzSumo:什么样的文章能获得疯转?(基于1亿篇文章大数据分析)
    深度学习成长的烦恼
    猜你喜欢-----推荐系统原理介绍
    程序设计小问题
    机器学习是什么--周志华
    提高matlab运行速度和节省空间的心得
    matlab提速技巧(自matlab帮助文件)
  • 原文地址:https://www.cnblogs.com/houhoujun/p/4416128.html
Copyright © 2011-2022 走看看