1 引用的意义
-
引用作为变量别名而存在,因此在一些场合可以代替指针
-
引用相对于指针来说具有更好的可读性和实用性
-
swap
函数的实现对比//指针方法 void swap(int* a,int* b) { int t = *a; *a = *b; *b = t; } //引用方法 void swap(int& a,int& b) { int t = a; a = b; b = t; }
-
注意:函数中的引用形参不需要初始化,它的初始化发生在函数调用的时候
2 特殊的引用
-
const
引用-
在 C++ 中可以声明
const
引用 -
const Type& name = var;
-
conts
引用让变量拥有只读属性int a = 4; const int& b = a; int* p = (int*)&b; //等价于对变量a取地址 b = 5; //error: assignment of read-only reference 'b' *p = 5; //正确,修改变量a的值
-
-
当使用常量对
const
引用进行初始化时,C++ 编译器会为常量值分配空间,并将引用名作为这段空间的别名const int& b = 1; int* p = (int*)&b; b = 5; //error: assignment of read-only reference 'b' *p = 5; //正确: 修改变量a的值
- 使用常量对
const
引用初始化后将生成一个只读变量
- 使用常量对
-
问题:引用有自己的存储空间么?
-
有!
-
Demo
#include <stdio.h> struct TRef { char& r; }; int main(int argc, char *argv[]) { char c = 'c'; char& rc = c; TRef ref = { c }; printf("sizeof(char&) = %d ", sizeof(char&)); //1 printf("sizeof(rc) = %d ", sizeof(rc)); //=> sizeof(c) = 1 printf("sizeof(TRef) = %d ", sizeof(TRef)); //0? printf("sizeof(ref.r) = %d ", sizeof(ref.r)); //=> sizeof(c) = 1 return 0; }
-
运行结果
sizeof(char&) = 1 sizeof(rc) = 1 sizeof(TRef) = 4 sizeof(ref.f) = 1
-
3 引用的本质
-
引用在 C++ 中的内部实现是一个指针常量
Tyep& name; void f(int& a) { a = 5; } //等价于 Type* const name; void f(int* const a) { *a = 5; }
-
注意
- C++ 编译器在编译过程中用指针常量作为引用的内部实现,因此引用所占用的空间大小与指针相同
- 从使用的角度,引用只是一个别名,C++ 为了实用性而隐藏了引用的存储空间这一细节
-
引用的存储空间
-
Demo
#include <stdio.h> struct TRef { char* before; char& ref; char* after; }; int main(int argc, char* argv[]) { char a = 'a'; char& b = a; //1)取变量a的地址 2)将a的地址赋值给b对应的4个字节的内存空间中去 char c = 'c'; TRef r = {&a, b, &c}; printf("sizeof(r) = %d ", sizeof(r)); printf("sizeof(r.before) = %d ", sizeof(r.before)); printf("sizeof(r.after) = %d ", sizeof(r.after)); printf("&r.before = %p ", &r.before); printf("&r.after = %p ", &r.after); return 0; }
-
编译运行
sizeof(r) = 12 sizeof(r.before) = 4 sizeof(r.after) = 4 &r.before = 0xbf8a300c &r.after = 0xbf8a3014
-
-
函数引用返回:返回局部变量的引用/指针可能会造成内存泄漏
-
Demo
#include <stdio.h> int& demo() { int d = 0; printf("demo: d = %d ", d); return d; //error: 返回局部变量的引用 <=> return &d } int& func() { static int s = 0; printf("func: s = %d ", s); return s; //返回静态局部变量 => 正确,静态变量不会随着函数调用的返回而被摧毁 } int main(int argc, char* argv[]) { int& rd = demo(); int& rs = func(); printf(" "); printf("main: rd = %d ", rd); printf("main: rs = %d ", rs); printf(" "); rd = 10; rs = 11; demo(); func(); printf(" "); printf("main: rd = %d ", rd); printf("main: rs = %d ", rs); printf(" "); return 0; }
-
编译
test.cpp: In function ‘int& demo()’: test.cpp:5:9: warning: reference to local variable ‘d’ returned [-Wreturn-local-addr] int d = 0; ^
-
运行
demo: d = 0 func: s = 0 main: rd = 13209588 <=>rd 等价于一个野指针 main: rs = 0 demo: d = 0 func: s = 11 main: rd = 132095588 main: rs = 11
-