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



     

  • 相关阅读:
    上海第八中学 shader
    http://www.riemers.net/
    手写板驱动
    使用dos 作为中介实现cpython 和c# 交互
    判断一个点是不是在三角形中 用面积算法
    Python os.chmod
    Python 的stat 模块
    文件格式说明
    win7 一切软件都安装不上 解决 把他卸掉
    执行力
  • 原文地址:https://www.cnblogs.com/wangkeqin/p/9302516.html
Copyright © 2011-2022 走看看