引用
引用为对象起了一个另外的名字,引用类型引用另外一种类型。通过将声明符写成&d的形式来定义引用类型,其中d是声明的变量名:
int digit = 10086;
int &number = digit;
number 指向 digit,即 number 是 digit 的另一个名字。
int &error;
报错,引用必须被初始化
定义了一个引用后,对其进行的所有操作都是在与之绑定的对象上进行的:
number = 10010;
此处将10010赋值给了 number 绑定的对象 digit
int temp = number;
与 temp = digit 的执行结果相同,temp 被初始化为 digit 的值
注意:
除了两种例外情况,其他所有引用的类型都要和与之绑定的对象严格匹配。
double value = 3.1415;
int &number = value;
报错,此处引用类型必须是int型对象
int &number = 10000;
报错,引用类型的初始值必须是对象
第一种例外
在初始化常量引用时允许用任意表达式作为初始值,只要改表达式的结果能转换成引用的类型即可。允许喂一个常量引用绑定非常亮的对象、字面值,甚至是个一般表达式:
int i = 100;
const int &ref_1 = i;
const int &ref_2 = 10;
const int &ref_3 = ref_1 * 10;
为了便于理解这种例外情况,我们来看一下当一个常量引用被绑定到另外一种类型上时发生了什么:
double test = 2.7;
const int &ref_test = test;
此处 ref_test 引用了一个int型的数,对 ref_test 的操作应该是整数运算,但 test 却是一个双精度浮点数。因此为了确保让 ref_test 绑定一个整数,编译器把上述代码变成了如下形式:
const int temp = test;
由双精度浮点数生成一个临时的整型常量
const int &ref_test = temp;
使 ref_test 绑定这个临时量对象
临时量对象: 编译器需要一个空间来暂存表达式的求值结果时临时创建的一个未命名的对象。
第二种例外
存在继承关系的类是一个重要的例外:我们可以将基类的指针或引用绑定到派生类对象上。
其具有一层极为重要的含义:当使用基类的引用(或指针)时,实际上我们并不清楚该引用(或指针)所绑定对象的真实类型。该对象可能是基类的对象,也可能是派生类的对象。