zoukankan      html  css  js  c++  java
  • C++11之右值引用

    ----------------------------右值引用---------------------------------

    右值定义:

      通俗来讲,赋值号左边的就是左值,赋值号右边的就是右值。可以取地址是左值,不可以取地址的是右值。C++11,之前没有明确提出右值的概念,所以 C++11 以前这些说活都是正确的。

      C++11 中的左值,仍然等同于 C++98 左值。C++11 中的右值,除了 C++98 中的右值以外,增加了将亡值的概念。 


      如下图

    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        int a; int & lref = a;
        //int && rref = a;   //!error:右值引用不能接受左值
        //int & elref = a*34; //!error:普通引用不能接受临时值
            const int &eclref = a*34;
        int && erref = a*34;
        return 0;
    }

     const T & 万能常引用

       其本质也是产生了临时对象, 并且该临时对象是 const 的。 此对于非基本数据类型也适用, 但需要转化构造函数。 

    class A
    {
    public:
      A(){
        cout<<"A() "<<this<<endl;
      }
      ~A(){
      cout<<"~A() "<<this<<endl;
      }
      A(const A &another)
      {
      cout<<"A(const A&)"<<&another<<"->"<<this<<endl;
      }
      void dis()
      {
        cout<<"xxxxoooooooooooo"<<endl;
      }
    };


    A getObjectA()
    {
      return A();
    }


    int
    main(int argc, char *argv[]) {   // int& ri = 5;   // const & cri = 5;   // float f = 34.5;   // int & irf = f;   // const int & cirf = f;   // A objA;   // int& irA = objA;   // const int& cirA = objA;   // cout<<cirA<<endl;   const A& ret = getObjectA();   ret.dis(); //!error:一个const对象,没有const函数,不能再完成调用。   return 0; }

      此种举措,也可以在返回中避免临时对象,再次拷贝和销毁。但时临时对象的性质是 const 的,也会给后续的使用带来不便。
     

     右值引用与左值引用的对比
    1) 都属于引用类型。
    2)都必须初始化。 左值引用是具名变量值的别名, 右值引用是匿名变量的别名。
    3) 左值引用, 用于传参, 好处在于, 扩展对象的作用域。 则右值引用的作用就在于延长了临时对象的生命周期。
    4)  避免“先拷贝再废弃” 带来的性能浪费。
    5)  对将亡值进行引用的类型; 它存在的目的就是为了实现移动语义

     const T & 与T && 本质对比

    #include <iostream>
    
    using namespace std;
    
    int main( )
    {
      const int & i =10;
     int && iii = 10 }

    /*
    int && iii = 10的汇编代码
    0x08048400  mov    $0xa,%eax
    0x08048405  mov    %eax,-0xc(%ebp)
    0x08048408  lea    -0xc(%ebp),%eax
    0x0804840b  mov    %eax,-0x4(%ebp)

    第一句将10赋值给eax,第二句将eax放入-0xc(%ebp)处,“临时变量会引用关联到右值时,右值被存储到特定位置”,-0xc(%ebp)便是该临时变量的地址,后两句通过eax将该地址存到iii处。

    通过上述代码,我们还可以发现,在上述的程序中-0x4(%ebp)存放着右值引用iii,-0x8(%ebp)存放着左值引用,-0xc(%ebp)存放着10,而-0x10(%ebp)存放着1,左值引用和右值引用同int一样是四个字节(因为都是地址)

    const int & i =10的汇编代码
    0x08048583  mov    $0xa,%eax
    0x08048588  mov    %eax,-0x8(%ebp)
    0x0804858b  lea    -0x8(%ebp),%eax
    0x0804858e  mov    %eax,-0x4(%ebp)

    -0x4(%ebp)处存放着i,-0x8(%ebp)处则存放着临时对象10,程序将10的地址存放到了i处。看到这里会发现const引用在绑定右值时和右值引用并没有什么区别。

    */

    参考:https://www.cnblogs.com/likaiming/p/9045642.html

    重要的事情再说一遍:  

      总之读完该篇博文你只需要知道:右值引用存在的意义就在于它既获得了同const T&同样的效率,又解决了const引用不可作为non-const类型使用的问题!

      想要更深入的了解右值引用以及他的作用:请参考另一篇博文:https://www.cnblogs.com/wangkeqin/p/9338358.html



     

  • 相关阅读:
    Populating Next Right Pointers in Each Node II
    Populating Next Right Pointers in Each Node
    Construct Binary Tree from Preorder and Inorder Traversal
    Construct Binary Tree from Inorder and Postorder Traversal
    Path Sum
    Symmetric Tree
    Solve Tree Problems Recursively
    632. Smallest Range(priority_queue)
    609. Find Duplicate File in System
    poj3159最短路spfa+邻接表
  • 原文地址:https://www.cnblogs.com/wangkeqin/p/9302516.html
Copyright © 2011-2022 走看看