C++的引用

  一般所说的引用指的都是左值引用(C++ 11新增了"右值引用”),是为对象起了另外一个名字,可以理解为对象的别名。定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用将和它的初始值对象一直绑定在一起,因此无法令引用重新绑定到另外一个对象。

引用变量定义

  int ival = 1024;

  int &refval = ival;    //定义引用变量refval,将其绑定到ival,是ival的另外一个名字

  int &refval;      //报错,引用必须初始化

  定义一个引用后,对其进行的所有操作都是对其所绑定对象的操作:

  refval = 2;      //把2赋给refval所绑定的对象,即将ival修改为2

  int ii = refval;      //与ii = ival执行结果一样,ii初始值为2

引用变量用在函数中

  在C语言中,函数的参数传递有两种方式:值传递和地址传递,C++中有了引用后,因此函数的参数传递新增一种方式:引用传递。

  值传递:将实参值拷贝到形参变量中,在函数中对形参变量的操作不会对实参变量产生任何影响。

  地址传递:将实参的地址拷贝到形参指针变量中,在函数中可以通过局部指针变量修改实参变量值。

  引用传递:不做临时拷贝,形参只是实参的别名而已,所以对形参变量的操作其实就是对实参变量的进行操作。

  int foo(int v1, int v2);      //值传递,实参被拷贝到形参v1、v2中,对v1、v2的访问和修改对实参不会有任何影响

  int foo(int *pv1, int *pv2);    //地址传递,实参的地址被拷贝到形参指针变量pv1, pv2中,通过指针pv1, pv2可修改实参值

  int foo(int &v1, int &v2);     //引用传递,参数v1, v2都是引用,即实参的别名,对v1、v2的修改将改变实参值

 

右值引用

  右值引用是C++ 11新增的引用类型,用于支持对象移动操作。

  右值引用就是必须绑定到右值的引用,使用&&定义。

  类似左值引用,右值引用也是某个对象的另一个名字。对于左值引用,不能将其绑定到要求转换的表达式、字面常量或是返回右值的表达式,而右值引用完全相反:可以将一个右值引用绑定到这类表达式,但不能讲一个右值引用绑定到一个左值上。

  int i = 42;

  int &r = i;         //正确,r绑定到i

  int &&rr = i      //错误,不能将右值引用绑定到左值上

  int &r2 = i * 42;    //错误,i * 42是个字面值

  const int &r2 = i * 42;    //正确,可以将一个const的引用绑定到右值上

  int &&rr2 = i *42;      //将rr2绑定到乘法结果(字面值)

  int &&rr1 = 42;       //正确,字面值常量是右值

  int &&rr2 = rr1;       //错误,rr1是右值引用变量,而变量都是左值,因此不能将右值引用绑定到变量上,即使是右值引用变量也不行

  返回左值引用的函数,连同赋值、下标、解引用和前置递增/递减运算符,都是返回左值的表达式,可以将左值引用绑定到这类表达式的结果上;返回非引用类型的函数,连同算术、关系、位以及后置递增、递减运算符,都生成右值,不能将左值引用绑定到这类表达式上,但可以将一个const的左值引用或一个右值引用绑定到这类表达式上。

  右值引用主要用于C++ 11新引入的移动构造函数和移动赋值运算符,这里不涉及。

 

注意事项(都是说左值引用):

  引用必须初始化;

  无法令引用重新绑定到另外一个对象;

  引用并非对象;

  引用不是一个对象,所以不能定义引用的引用;

  引用只能绑定到对象上,而不能与字面值或某个表达式的计算结果绑定在一起。

posted on 2018-03-25 12:06  泣血  阅读(381)  评论(0编辑  收藏  举报

导航