引用的主要用途是为了描述函数的参数和返回值,特别是为了运算符的重载。
对"普通" T& 的初始式必须是一个类型 T 的左值,左值引用只能是对左值的引用:
int i;
int& cdi = i; // ok
double& cdr = 1; // error
const short sval = 1024;
short& cds = sval; // error
对一个 const T&
的初始式不必是一个左值,甚至可以不是类型 T(如函数调用时)。在这种情况下:
- 首先,如果需要将应用到 T 的隐式类型转换
- 而后将结果存入一个类型 T 的临时变量
- 最后,将此临时变量用作初始式的值
这种保存引用初始式的临时变量将一直存在,直到这个引用的作用域结束。
int i;
const int& cdi = i; // ok
const double& cdr = 1; // ok
const short sval = 1024;
const short& cds = sval; // ok
常引用作为万能引用,其既可以是对左值的引用,也可以是对右值的引用。
就是引用在定义的时候必须初始化关联到一个对象(必须事先存在一个对象)。
引用从"出生"开始,便与某个对象绑定,中途无法解绑。
Object a = { 1 };
Object b = { 2 };
Object& r = a; // r 与对象a绑定
r = b; // 这并不是重新绑定。只是把b对象的值赋给了a。此时 a 与 b 数值上相同。
从上面的代码可以看出,相对之下,指针的使用则较为灵活,一个指针可以先指向对象a,再指向对象b。而引用多用于函数传参时候,无论是普通类型传参,还是涉及到多态。