首先看下面的代码:
double dval = 3.14;
const int &ri = dval;
dval = 5;
运行发现结果是这样的:
我们都知道,引用就相当于所绑定的对象的一个别名,我们修改对象的值的同时也会修改引用的值,那么为什么在上面那段代码中我们修改dval的值却不会影响的它的引用ri的值呢,要想弄清原因,我们就得知道当一个常量引用被绑定到另一种类型上时发生什么。
上面那段代码中,ri引用了int型的数,对ri的操作应该是整数运算,但dval却是一个双精度浮点数而非整数。因此为了确保ri绑定的是一个整数,编译器会把上面那段代码变成:
double dval = 3.14;
const int temp = dval;
const int &ri = temp;
发现了吗,ri绑定的对象并不是dval,而是一个临时量temp,所以此时无论你怎么改变dval的值都不会影响到ri的值,这就是为什么修改dval的值为5后ri的值认为3的原因。
我们再来探讨下当ri不是常量时会怎么样,理论上为了让ri绑定的是一个整型对象,编译器任得这么做
double dval = 3.14;
int temp = dval;
int & ri = temp;
如果ri不是常量,就允许对ri赋值,这样就会改变ri所绑定对象的值,值得注意的是,上面ri绑定的是临时量temp,我们既然让ri绑定dval,就肯定是想通过ri来改变dval的值,否则干嘛要给ri赋值呢,如此,我们也不会想着把引用绑定到临时量上面吧,所以C++也把这种行为归为非法,即不允许将一个非常量引用绑定到另外一种类型的对象上:
而当第一段代码中的dval类型为int时又会怎样呢?
int dval = 3.14;
cosnt int &ri = dval;
此时的dval为int型,和引用ri的类型一致,所以编译器并不会将ri绑定到一个临时量上,所以当dval的值被修改是,ri的值也会跟着被修改: