引用就像是能够自动被编译器间接引用的常量型指针。
c++不允许通过 void* “中转”,使得不同类型指针相互赋值,相对于c 来说,是一种类型要求更强的语言。
引用不可以只声明,而不初始化。
引用 《------》存储单元
应用要点:
任何引用必须和存储单元联系,访问引用时就是在访问这个存储单元。这是一个奇特的指针。
(1)引用被创建时必须被初始化(指针可以在任何时候初始化)
(2)一旦引用被初始化为指向一个对象,就不能改变为另一个对象的引用 (指针则可以任何时候指向另一个对象)
(3) 不可能有NULL引用,必须确保引用是和一块合法的存储单元联系。
e.g.
int x = 10
int &a = x;
(gdb) p a
$1 = (int &)@0x100407010: 10
(gdb) p &a
$2 = (int *) 0x100407010 <x>
(gdb) p *&a
$3 = 10
注意:
int y = 111;
int * p = &y;
&a = p 编译错误:赋值运算 左操作数必须是左值
函数引用
17 int & j(){
18 int q;
19 return &q;
20 }
21
22 int & m(){
23 int q;
24 return q;
25 }
26
27 int & i(){
28 const int q = 100;
29 return &q;
30 }
31 int & c(){
32 const int q = 100;
33 return q;
34 }
int & j()中:错误 用类型为 int* 的右值初始化为 int& 的非常量引用无效
int & m() 中:警告:返回了对局部变量 q 的引用
int & i() 中:错误:用类型为 const int * 的右值初始化为 int & 的非常量引用无效
int & c() 中 :错误 :将类型 int& 的引用初始化为类型为 const int 的表达式无效
常量引用
在函数参数中使用常量引用是非常重要的。
void f(int &){}
void g(const int &){}
int main(){
f(100);
g(100);
}
f(100) 错误:用类型为int 的右值初始化类型为 int& 的非常量引用无效
编译器首先必须建立一个引用,为int类型分配存储单元,同时初始化为100并为其产生一个地址和引用捆绑在一起。存储的内容必须为常量,不能再对其进行操作。
指针引用
void increment(int * & i){i++;}
int main(){
int * i = 0;
increment(i);
}