C++中const引用的初始化

初始化const引用时允许用任意表达式作为初始值,只要该表达式的结果能转化成引用的类型即可。允许为一个常量引用绑定非常量的对象、字面值、甚至是一个表达式:

int i = 42;
const int &r1 = i;       //允许将cont int&绑定到普通int对象上
const int &r2 = 42;      //正确:绑定到字面值
const int &r3 = r1 * 2;  //正确:绑定到表达式
int &r4 = r1 * 2;        //错误:r4是一个普通的非常量引用,不能绑定到一个右值

当一个const引用绑定到另外一种类型上时,会发生什么?

先看看当一个const引用绑定到相同的类型时:

int i = 42;
int &ri = i;           //ri是一个普通引用,绑定到i
const int &cri = i;    //const int& 绑定到普通int对象
cout << cri << endl;
ri = 0;                //通过ri改变了i
cout << cri << endl;

输出结果是:

42

0

原因是cri虽然是一个const引用,我们不能通过它改变它所引用的对象的值,但是引用的对象i本身并不是一个常量,可以通过其他途径改变i的值。

当const引用绑定到另外一种类型时,情况会有所不同:

int i = 42;
int &ri = i;
const double &cri = i;
cout << cri << endl;
ri = 0;
cout << cri << endl;

输出结果:

42

42

这里我们把cri的类型改成了const double&,它将绑定到一个double类型对象上,但是事实上我们初始化了一个int对象,这时候编译器会把初始化代码变成如下形式:

const double temp=i;      //生成一个临时double常量
const double &cri=temp;   //让cri绑定到这个临时量

cri实际上是绑定到编译器生成的临时double常量上,并没有绑定到i上。