1. 左值引用的定义
左值引用实际上是一种隐式的指针,它为对象建立一个别名,通过操作符&来实现。
// 左值定义格式 数据类型 & 表达式 // 实例 int a=10; int & fly_a=a; fly_a = 2; // 左值引用,隐式的指针
左值引用的特点:
1. 一个C++引用被初始化后,无法使用它再去引用另一个对象,它不能被重新约束。
2. 引用对象只是其他对象的别名,对它的操作和对原来变量的操作具有同样作用。
3. 指针变量与引用有两点主要区别:
3.1 指针是一种数据类型,而引用不是一个数据类型。指针可以转换为它所指向的变量的数据类型,以便赋值运算两边的类型相匹配;使用引用时,系统要求引用和变量的数据烈性必须相同,不能进行类型转换。
3.2 指针变量和引用变量都用来指向其他变量,但是指针变量使用的语法要更复杂一些。
2. 右值引用的定义右值引用可以理解为右值得引用,当右值引用初始化后,临时变量消失。
// 定义格式 类型 && i=被引用的对象 // 实例如下 #includeint get() { int i=4; return i; } int main(void) { int && k = get()+4; // int & i=get()+4; //出错 k++; std::cout << "k 的值" << k << std::endl; return 0; }
输出为9.
右值引用的特点:
1. 一个右值引用被初始化后,无法使用它再去引用另一个对象,它不能被重新约束。
2. 右值引用初始化后,具有该类型数据的所有操作。
3. 右值引用只可以初始化右值,但右值引用实质上是一个左值,它具有临时变量的数据类型。
3. 左值和右值的区别
1 .左值可以寻址,而右值不可以。
2 .左值可以被赋值,右值不可以被赋值,可以用来给左值赋值。
3 左值可变,右值不可变(仅对基础类型适用,用户自定义类型右值引用可以通过成员函数改变)。
例如const int&a = 1等,那么他和const int a = 1,有什么不同呢,从语法上讲后者的右值在表达时结束后就销毁了,而前者不会。这就是我们尽量用const 引用代替值传递做函数参数的原因,它在某种程度上可以提高效率。
那么右值引用有什么用呢?看一个例子。T&& a = ReturnValue(); 当我们调用一个返回一个右值的函数时,当函数返回后,函数返回的右值生命周期也就结束了,但是当我们通过一个右值引用来接收时,该右值有重新获生命,只要我们的右值引用a存在,该右值也同时存在,这又有什么用呢,当我们使用T a = ReturnValue();这样的方式来接收时,会多一次对象的析构和构造,首先用函数返回值构造a,然后函数返回值生命期结束析构。而右值引用则不会,因为右值引用直接绑定了函数返回的右值。
4. 万能引用
只有两种形式的引用:左值引用和右值引用,万能引用不是一种引用类型,而是代表要么是左值引用要么是右值引用。
1、万能引用用在需要推断类型的场合,即以下两种场合:
1. 用在模板
templatevoid tempFun(T&& t) {} //模板类型的这种用法 T && 是万能引用最常见的使用场合
2. auto推断类型
auto&& var2 = var1; //auto这种需要推断类型的地方
万能引用虽然跟右值引用的形式一样,但右值引用需要是确定的类型,如: int && ref = x;
2、万能引用能够接收左值或右值,返回左值引用或右值引用。
templatevoid tempFun(T&& t) { t = 40; cout << t << endl; } int main() { int x = 19; tempFun(x); //T为int, t为int & ,即左值引用, 函数模板中对t的改动为影像x的值 tempFun(30);//T为int, t为int&&,即右值引用 int &&r = 100; tempFun(r); //虽然r绑定到一个右值,但r变量本身是个左值(因为他出现在=的左边) return 0; }



