初始化引用
引用类型的变量必须使用引用类型派生自的类型的对象进行初始化,或使用可转换为引用类型派生自的类型的类型的对象进行初始化。 例如:
// initializing_references.cpp
int iVar;
long lVar;
int main() {
long& LongRef1 = lVar; // No conversion required.
long& LongRef2 = iVar; // C2440
const long& LongRef3 = iVar; // OK
LongRef1 = 23L; // Change lVar through a reference.
LongRef2 = 11L; // Change iVar through a reference.
LongRef3 = 11L; // C3892
}
使用临时对象初始化引用的唯一方式是初始化常量临时对象。 初始化后,引用类型变量始终指向同一对象;不能将它修改为指向另一个对象。
尽管语法可以相同,但引用类型变量的引用和引用类型变量的赋值在语义上不同。 在前面的示例中,更改 iVar 和 lVar 的赋值看起来像初始化,但它们有不同的效果。 初始化指定引用类型变量指向的对象;赋值通过引用向引用目标对象赋值。
由于将引用类型的参数传递给函数或从函数返回引用类型的值都是初始化,因此会正确初始化函数的形参,就像它们是返回的引用一样。
只有在下列声明中才能在没有初始值设定项的情况下声明引用类型变量:
函数声明(原型)。 例如:
int func( int& );
函数返回类型声明。 例如:
int& func( int& );
引用类型类成员的声明。 例如:
class c { public: int& i; };
显式指定为 extern 的声明。 例如:
extern int& iVal;
初始化引用类型变量时,编译器将使用下图中所示的决策关系图,在创建对对象的引用或创建引用所指向的临时对象之间做出选择。
引用类型初始化决策图
可使用同一类型的 volatile 对象或使用尚未声明为 volatile 的对象初始化对 volatile 类型(已声明为 volatile typename**&** identifier)的引用。 但是,不能使用该类型的 const 对象初始化它们。 同样,可使用相同类型的 const 对象(或具有到该类型的转换或具有尚未声明为 const 的对象的任何内容)初始化对 const 类型(已声明为 const typename**&** identifier)的引用。 但是,不能使用该类型的 volatile 对象初始化它们。
未使用 const 或 volatile 关键字限定的引用只能使用既未声明为 const 也未声明为 volatile 的对象进行初始化。