引用的一些探求

引用的一些探求

 

本文参考阅读材料做的测试,对引用做了进一步的探求。

 

环境: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++基础与提高》 王桂林

 

posted @ 2021-03-23 23:39  bruce628  阅读(45)  评论(0)    收藏  举报