C++ 引用
定义:
- 已定义的变量的别名。
使用方法:
- 声明引用时必须将其初始化:
1 int rats=101; 2 int & rodents=rats;
注意:引用一旦被创建不能更改其与某个变量之间的关系,即引用不能再代表其他变量。 - 用作函数参数
- 引用仅仅是别名,使用引用的方法完全与原数据类型相同,但是注意decltype关键字等中的用法略有不同;
int i; int & j = i; // j type int & decltype (j) k = i; // k type int & but not int
- 允许多层引用但引用的仍是原来的数据
int i = 999; int & j = i; // j is the reference of i int & k= j; // k is the reference of i
用作函数参数时的注意事项:
-
当实参与引用参数不匹配时:
- 若参数为 const 引用且函数调用的参数不是左值或与相应的 const 引用参数的类型不匹配,则 C++ 将创建类型正确的匿名变量,将函数调用的参数的值(实参值)传递给该匿名变量(实参值可以被强制转换为相应类型时),并让参数来引用该变量。这些匿名变量只在函数调用期间存在,此后编译器便可以随意将其删除。因此对于实参为 const 引用的 C++ 函数,如果实参不匹配且可以发生强制类型转换,则其行为类似于按值传递。(例外的是有时非 const 右值引用参数也可达到类似生成匿名变量的效果:如 double && 形参可以输入无关左右值的 int 和 const int 类型实参)
注(什么是左值?):左值参数是可被引用的数据对象,例如变量、数组元素、结构成员、引用和解除引用的指针都是左值。非左值包括字面常量(用引号括起的字符串除外,他们由其地址表示)和包含多项的表达式。
-
尽可能使用 const:
- 使用 const 可以避免无意中修改数据的编程错误。
- 使用 const 能使函数能处理 const 和非 const 实参,否则将只能接受非 const 数据。
-
使用 const 引用使函数能够正确生成并使用临时变量。
函数返回引用时需要注意的事项:
-
避免返回函数终止时不在存在的内存单元引用,解决办法:
- 返回一个作为参数传递给函数的引用。
- 用 new 来分配新的存储空间。
- 必要时将返回类型声明为 const 引用,可避免犯糊涂;通过省略 const ,可以编写更简短代码,但其含义也更模糊,增加了犯错的机会,然而有时省略 const 确实有道理。
1 free_throws & clone(free_throws & ft) 2 { 3 ... 4 return ft; 5 } 6 7 clone(ft)=four; //it's allowed, four covered ft
const free_throws & clone(free_throws & ft) { ... return ft; } clone(ft)=four; //it's not allowed
display(clone(ft)); //it's allowed, you can ues it like this
将引用用于对象:
- 基类引用可以指向派生类对象,而无需进行强制类型转换。
void file_it(ostream & os) { ... } ofstream fout; file_it(fout);
例如:参数 os (其类型为 ostream & )可以指向 ostream 对象(如 cout ),也可以指向 ofstream 对象(如 fout )。
何时使用引用参数:
- 程序员能够修改调用函数中的数据对象。
- 通过传递引用而不是整个数据对象,可以提高程序的运行速度。
- 什么时候使用引用、什么时候使用指针,一般性指导原则是
- 对于使用传递的值而不作修改的函数:
- 如果数据对象很小,如内置数据类型或小型结构,则按值传递。
- 如果数据对象是数组,则使用指针,因为这是唯一的选择,并将指针声明为指向 const 的指针。
- 如果数据对象是较大的结构,则使用 const 指针或 const 引用,以提高程序的效率。这样可以节省复制结构所需的时间和空间。
- 如果数据对象是类对象,则使用 const 引用。类设计的语义常常要求使用引用,这是 C++ 新增这项特性的主要原因。因此,传递类对象参数的标准方式是按引用传递。
- 对于修改调用函数中数据的函数:
- 如果数据对象是内置数据类型,则使用指针。如果看到诸如 fixit(&x) 这样的代码(其中 x 是 int ),则很明显,该函数将修改 x 。
- 如果数据对象是数组,则只能使用指针。
- 如果数据对象是结构,则使用引用或指针。
- 如果数据对象是类对象,则使用引用。
- 对于使用传递的值而不作修改的函数:
右值引用:
- C++ 11 新增了右值引用——这种引用可指向右值,使用 && 声明,之前的引用称为左值引用。