zoukankan      html  css  js  c++  java
  • 左值引用,右值引用以及移动语义

    1.左值引用

    左值引用的基本语法

    Type &引用名 = 左值表达式;

    #include <iostream>
    using namespace std;
    int main()
    {
     int a = 10;
     //ra是a的引用(别名),相当于把ra与a绑定。
     int &ra(a);
     cout << ra << "  " << (void*)&ra << "  " << (void*)&a << endl;
     cin.get();
     return 0;
    }
    

     运行

    引用的基本规则

    1. 声明引用的时候必须初始化,且一旦绑定,不可把引用绑定到其他对象。
    2. 对引用的一切操作,就相当于对原对象的操作。

    2.右值引用

    以上是最常见的引用方式,我们称之为左值引用。为了顺利区分左右值引用的概念,我们先来看下左右值的概念。

    首先,左右值是表达式的属性。何为表达式?表达式由一个或多个运算对象组成。字面值和变量是最简单的表达式。

    一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址。

    int a = 1;

    a + 1;    //a + 1 是表达式

    在C++旧标准中,我们可以引用a,但却无法引用a+1,这是为什么呢?

    这是因为,变量a被创建后,在它的作用域内是一直存在的。如此一来,它的引用是有存在意义的。而a+1不是一个对象,在运算中临时存在于寄存器中,而寄存器中的值是时刻被刷新的,创建a+1的引用显得没有任何意义。为了成功的使用类似于a+1这种右值的引用。C++新标准提出了区别于以往的引用-右值引用。

    右值引用的基本语法

    Type &&引用名 = 右值表达式;

    #include <iostream>
    using namespace std;
    int main()
    {
     int a = 10;
     //右值引用
     int &&ra(a+1);
     cout << ra << ends << (void*)&ra << ends << (void*)&a << endl;
     ra++;
     cout << ra << endl;
     cin.get();
     return 0;
    }
    

     运行

    对右值引用的一种可能的内部实现解释

    int a = 1;

    int *p = new int(a + 1);

    int &ra = *p;

    delete p;      //不再使用引用了,动态内存的释放由C++自动管理

    其中第二、三两句就对应右值引用:int &&ra(a+1);

    3.引用作为函数参数

    引用作为函数参数时,有着指针一样的功能。

    #include <iostream>
    using namespace std;
    void fun(int &ra)
    {
     cout << ra << ends << (void*)&ra << endl;
     ra++;
    }
    int main()
    {
     int a = 10;
     fun(a);
     cout << a << ends << (void*)&a << endl;
     cin.get();
     return 0;
    }
    

     运行

    在函数fun内,对形参ra的值,做出了更改,这一操作影响了实参a。显然引用的使用比指针简单。

    4.引用与数组

    int a[]{1, 2, 3, 4, 5};

    int (&ra)[5] = a;    //对数组进行引用

    5.引用与指针

    引用一级指针

    int a(0), *p = &a;

    int *&rp = p;

    引用二级指针

    int a(0), *p = &a;

    int **pp = &p;

    int **&rp = pp;  //引用二级指针,若编译不通过,使用 int (**(&rp)) = pp;

    6.引用与函数指针

    #include <iostream>
    using namespace std;
    int add(int a, int b)
    {
     return a + b;
    }
    int sub(int a, int b)
    {
     return a - b;
    }
    int mul(int a, int b)
    {
     return a * b;
    }
    int divi(int a, int b)
    {
     if (b)
      return a / b;
     else
      return INFINITY;
    }
    int main()
    {
     int a(100), b(10);
     cout << "使用函数名" << endl;
     cout << add(a, b) << ends << sub(a, b) << ends << mul(a, b) << ends << divi(a, b) << endl;
     //padd是函数指针
     int(*pfun)(int, int); 
     cout << "使用函数指针" << endl;
     pfun = add;
     cout << pfun(a, b) << ends;
     pfun = sub;
     cout << pfun(a, b) << ends;
     pfun = mul;
     cout << pfun(a, b) << ends;
     pfun = divi;
     cout << pfun(a, b) << endl;
     //函数指针数组
     int(*pfuns[])(int, int){add, sub, mul, divi};
     cout << "使用函数指针数组" << endl;
     cout << pfuns[0](a, b) << ends << pfuns[1](a, b) << ends << pfuns[2](a, b) << ends << pfuns[3](a, b) << endl;
     cout << "函数指针的引用" << endl;
     int(*(&rfun0))(int, int)(pfuns[0]);
     int(*(&rfun1))(int, int)(pfuns[1]);
     int(*(&rfun2))(int, int)(pfuns[2]);
     int(*(&rfun3))(int, int)(pfuns[3]);
     cout << rfun0(a, b) << ends << rfun1(a, b) << ends << rfun2(a, b) << ends << rfun3(a, b) << endl;
     cin.get();
     return 0;
    }
    

     运行

  • 相关阅读:
    HSF原理
    Spring IOC 容器源码分析
    Spring Bean注册和加载
    CAP和BASE理论
    Java内存模型
    Java线程模型
    IO复用、多进程和多线程三种并发编程模型
    无锁编程本质论
    An Introduction to Lock-Free Programming
    安装与配置ironic
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/5374419.html
Copyright © 2011-2022 走看看