左值引用与右值引用
**左值:**在一定作用域中是可以寻址的就叫左值,比如变量、函数返回的引用类型、函数返回的const类型
int x = 10; // x是左值
int& add(int a, int b){
return a+b;
} // add函数返回的值是一个左值
const int add1(int a, int b){
return a+b;
} // add1函数返回的const类型也是一个左值
**右值:**临时的,不可以寻址的,只用于临时存储的就是右值,比如函数返回值、常数、立即数
10; // 10是一个立即数,是一个右值
int add2(int a, int b){
return a+b;
} // add2函数返回的值是一个右值
左值引用
int x = 10;
int &rref = x; // 这样的引用没有问题
但是,如果有下面的写法,编译器就将会报错
int &x = 10; // 编译无法通过
如若需要使用引用,可以改成
const int &x = 10;
//上面的代码等价于
const int a = 10;
const int &x = a;
使用这种引用方法虽然可以引用右值,但是无法对右值进行修改,因为它以常量的形式声明,而使用右值引用就能很好的解决这个问题
右值是一种不体现出来的内存地址空间,它没有被声明,用了之后就会被丢弃,是无法被访问到的,比如下面一段代码
#include <iostream>
using namespace std;
int my_add(int a, int b){
return a+b;
}
int main()
{
int &&x = my_add(5,6); // my_add的返回值是一个右值,
int a = x;
int b = x;
cout<<"r value address is:"<<&x<<endl;
cout<<"a is:"<<a<<endl;
cout<<"b is:"<<b<<endl;
}
r value address is:0x7911bffa4c
a is:11
b is:11
右值引用的格式
type &&lref = 右值;
C++对于左值和右值没有标准定义,但是有一个被广泛认同的说法:
- 可以取地址的,有名字的,非临时的就是左值;
- 不能取地址的,没有名字的,临时的就是右值;
右值引用是好好利用一些临时变量空间,从而减少对象的构造和析构频率来达到加速程序的作用,他是理解C++11中std::move和std::forward的基础