C++11--右值引用

1。左值、右值、左值引用、右值引用

https://www.jb51.net/article/85549.htm

https://www.jb51.net/article/136337.htm

https://www.cnblogs.com/qicosmos/p/4283455.html

通常意义上,在C++中,可取地址,有名字的即为左值。

不可取地址,没有名字的为右值。右值主要包括字面量,函数返回的临时变量值,表达式临时值等。

可以接受右值的右值引用本身却是个左值

#include<iostream>

#include<utility>

#include<vector>

using namespace std;

int f();

int main() {

    vector<int>vi(100);

    int i=42;

    int &&r1=i;//error不能把右值引用绑到左值上

    int &&r2=10;

    int &r3=i;

    int &r4=10;//error非常量引用不能绑到右值上

    const int &r5=10;//ok

    int &&r5=r2;//error,r2是左值

    int &&r6=std::move(r2);//ok,c++11std::move把左值转换为对应的右值引用类型。

    int &&r4=f();//这个函数返回右值

    int &r5=vi[1];//下标返回左值

    int &r6=r4;//变量r4是左值

}

//左值引用表示一个对象的身份,右值引用表示对象的值

//返回左值引用的函数、赋值、下标、解引用和前置递增递减运算符都是返回左值。

//不能把右值引用绑定在它们上,但可以把左值引用绑在它们上

//返回非引用类型的函数、算术、关系、位以及后置递增递减运算符、取地址&都是返回右值

//不能把左值引用绑定它们上,但可以把const左值引用和右值引用绑定在它们上。

1、左值和右值的概念

左值是可以放在赋值号左边可以被赋值的值;左值必须要在内存中有实体;
右值当在赋值号右边取出值赋给其他变量的值;右值可以在内存也可以在CPU寄存器。
一个对象被用作右值时,使用的是它的内容(值),被当作左值时,使用的是它的地址。

2、引用

引用是C++语法做的优化,引用的本质还是靠指针来实现的。引用相当于变量的别名。

引用可以改变指针的指向,还可以改变指针所指向的值。
引用的基本规则:

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

3、左值引用和右值引用

3.1 左值引用

左值引用的基本语法:type &引用名 = 左值表达式;

3.2 右值引用

右值引用的基本语法type &&引用名 = 右值表达式;

右值引用在企业开发人员在代码优化方面会经常用到。

右值引用的“&&”中间不可以有空格。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

#include <iostream>

using namespace std;

  

int main()

{

    cout << "-------引用左值--------" << endl;

    int a = 5;

    int &add_a(a);

  

    cout << " a =" << a <<" "<<" &a = "<<&a<< endl;

    cout << "add_a =" << add_a<<" "<< "&add_a = " << &add_a << endl;

    cout << "-----------------------" << endl;

  

    cout << "-------引用右值--------" << endl;

    int b = 10;

    int &&add_b(b + 1);

    cout << " b =" << b << " " << " &b = " << &b << endl;

    cout << "add_b =" << add_b << " " << "&add_b = " << &add_b << endl;

    add_b++;

    cout << "add_b++ =" << add_b << " " << "&add_b++ = " << &add_b << endl;

    cout << "-----------------------" << endl;

  

    system("pause");

    return 0;

}

其实对于左值还是很好理解的,主要是对于右值是不好理解的,特别是代码的16行处:右值的例子。C++之所以设计出右值引用的语法,主要是因为对于类似b+1;这样的运算是发生在CPU寄存器上的,就不能对其取地址、赋值等操作,所以这类运算只能放在等号的右边,将其赋给其他的变量。若等号右边出现:&b,这样的操作是,也是右值,因为取地址符的操作也是在寄存器中完成的。所以不能作为左值。

和右值引用相关的概念比较多,比如:右值、纯右值、将亡值、universal references、引用折叠、移动语义、move语义和完美转发等.

在C++11中所有的值必属于左值、将亡值、纯右值三者之一。比如,非引用返回的临时变量、运算表达式产生的临时变量、原始字面量和lambda表达式等都是纯右值。而将亡值是C++11新增的、与右值引用相关的表达式,比如,将要被移动的对象、T&&函数返回值、std::move返回值和转换为T&&的类型的转换函数的返回值等

2。std::move()与完善转发std::forward()

右值引用移动构造:相当于剪切

左值引用拷贝构造:相当于拷贝再删除

猜你喜欢

转载自blog.csdn.net/smartgps2008/article/details/90582832