引用类型由类型标识符和一个取地址操作符来定义, 引用必须被初始化.
请看下面的初始化:
double dval = 3.14159;
extern int f();
int &ir1 = 1024; // error
int &ir2 = dval; // error
int &ir3 = f(); // error
上面的三个引用初始化都将导致编译出错. 下面做适当解释.
实际上, 引用在内部存放的是一个对象的地址, 它是该对象的别名, 对于不可寻址的值, 比如文字常量, 以及不同类型的对象, 编译器为了实现引用, 必须生成一个临时对象, 引用实际上指向该对象, 但用户不能访问它. 比如, 我们写了:
double dval = 3.14159;
int &ir2 = dval;
由于需要类型转换, 因此编译器将其转换成:
int temp = dval; int &ir2 = temp; // 如果这时候给ir2赋一个新值, 那么改变的是temp, 而不是dval.
// 而temp是不可寻址的. 同时 对于用户来说, 并不想这么做.
因此, 这种情况下, 我们需要const引用, 因为它们是只读的, 不允许非const引用指向需要临时对象的对象或值. 另外, 对于int &ir3 = f(), f()函数调用的返回值也是一个临时值, 不能被用来初始化非const型的引用.
正确的修改如下:
const int &ir1 = 1024; // OK
const int &ir2 = dval; // OK
const int &ir3 = f(); // OK