引用的一些探求
引用的一些探求
本文参考阅读材料做的测试,对引用做了进一步的探求。
环境:Centos7,x86-64位;
工具:g++;
一.引入
1 #include <iostream> 2 3 using namespace std; 4 5 void foo(int &a, int &b) 6 { 7 cout<<sizeof(a)<<", "<<sizeof(b)<<endl; 8 } 9 10 int main() 11 { 12 int a; 13 int b; 14 foo(a, b); 15 16 return 0; 17 }
执行结果如下:
1 4, 1
通过函数求引用的大小,结果仍然是所引用对象的大小,而不是引用本身的大小。
二.求引用的大小
上面求引用的大小,貌似并非正确的方式,引用总会在函数调用的时候被初始化为所引用对象的大小。
将其封装一下试试
代码如下:
1 #include <iostream> 2 3 using namespace std; 4 5 struct TypeP 6 { 7 char *p; 8 }; 9 10 struct TypeC 11 { 12 char c; 13 }; 14 15 struct TypeR 16 { 17 char &r; 18 }; 19 20 int main() 21 { 22 cout<<sizeof(TypeP)<<", "<<sizeof(TypeC)<<", "<<sizeof(TypeR)<<endl; 23 24 return 0; 25 }
执行结果如下:
1 8, 1, 8
将引用放到一个结构体中,省却了其一定要初始化的环节,这样求得的引用的大小,就是真实的引用的大小了。
通过结果,可以看到封装了引用的结构体,其大小为8个字节,与指针的大小一样,初步推测其为指针。
三.初始化
C++中只有const类型的数据必须要初始化,而引用也必须要初始化,所以引用是指针,还应该是const类型修饰的指针。
四.结论
综上所述,引用的本质是const修饰的指针,即const ElementType &ref。其功能类似指针,看起来又不是指针,是对指针的封装。
五.验证
对一个功能相同的函数,分别用指针和引用两种方式来编写,汇编得到的结果是一致的。
代码如下:
1 #include <iostream> 2 3 using namespace std; 4 5 void swapPtr(int *p, int *q) 6 { 7 int t = *p; 8 *p = *q; 9 *q = t; 10 } 11 12 void swapRef(int &p, int &q) 13 { 14 int tmp = p; 15 p = q; 16 q = tmp; 17 } 18 19 int main() 20 { 21 int a = 3; 22 int b = 5; 23 swapRef(a, b); 24 swapPtr(&a, &b); 25 26 return 0; 27 }
进行反汇编
1 [root@db01 CPP]# g++ -g -o test4 test4.cpp 2 [root@db01 CPP]# objdump -S -d test4
结果如下:

参考材料:
《C++基础与提高》 王桂林
浙公网安备 33010602011771号