概念
右值引用是下面这样的(引用右值):
int&& a = 10;
右值引用、左值引用和常引用
右值引用不能引用左值,左值引用也不能引用右值。
int main()
{
int a = 10;//a是左值
const int b = 20;//b是常变量,20是字面常量
int& ra = a;//左值引用
//int& rb = b;//error,左值引用不能引用字面常量
int&& rc = 10;//右值引用,可以引用右值
//int&& rd = a;//error
return 0;
}
常引用是万能引用——左值、右值都可引用。
int main()
{
int a = 10;
const int b = 20;
const int& rb = b;//常引用,可以引用一切(左值和右值)
const int& rx = 10;
const int& rz = a;
}
区别:
左值引用是给变量一个别名,而右值引用不是起别名,引用可以改而被引用本身不变。
右值引用的临时量可以修改,而常引用不能改。
int main()
{
int&& a = 10;
a += 100;
//是给临时的a改,a = 110
const int rb = 20;
//rb += 1;//error
}
相同的 :
无论声明左值引用还是右值引用都必须立即初始化 ;
右值引用的右值生命周期与右值引用名绑定。
引用的值传递
C11里几乎没有值传递。
由于常引用是万能引用类型,遇到合适的,编译器会控制调用优先级。
//void func(int a){}
void func(int& b) { cout << "左值引用" << endl; }
void func(const int& c) {cout<< "常性左值引用" << endl; }
//void func(int&& d) { cout << "右值引用" << endl; }
int main()
{
//func(10);//error,a,d产生编译的二义性,可以是值传递,也可以是右值引用传递
int a = 10;
//编译器控制调用优先级
//传左值
func(a);//优先与左值引用 再与 左值常引用关联
//传右值
func(10);//优先与右值引用关联 再与 左值常引用关联
//传常变量
const int b = 10;
func(b);//只能与常性左值引用关联
}
各种类型的返回
值返回
函数构建将亡值返回,即右值,此时不能用左值引用接收:int &a = fun();
左值返回
将亡值存在调用的函数中
右值返回
建立的临时量还再fn中
类类型返回
程序值返回时,拷贝构造产生将亡值
若声明与初始化在一起:Int a = fun(1)//a就是这个将亡值
若先声明再初始化Int b;b = fun(2);//把将亡值赋给b,再把将亡值删掉
右值引用比普通的返回少了拷贝构造和析构,因为右值引用绑定了右值,让临时右值生命周期延长。