第5课 - 引用的本质分析

第5课 - 引用的本质分析

1. 引用的意义

  (1)引用作为变量别名而存在,因此在一些场合可以代替指针

  (2)引用相对于指针来说具有更好的可读性实用性

  

注意: ① 一般在声明引用时,必须对其进行初始化    ② 函数中的引用形参不需要进行初始化!!!初始化发生在函数调用的时候。

2. 特殊的引用:const引用

  (1)在 C++ 中可以声明 const 引用,形式如下:const  Type&  name = var;   const引用让变量拥有只读属性

  (2)当使用常量对 const 引用进行初始化时,C++编译器会为常量值分配空间,并将引用名作为这段空间的别名

 1 #include <stdio.h>
 2 
 3 void Example()
 4 {
 5     printf("Example:\n");
 6 
 7     int a = 4;    // i可以更改
 8     const int& b = a;    // b不可以更改
 9     int* p = (int*)&b; 
10 
11     //b = 5;
12 
13     *p = 5;
14 
15     printf("a = %d\n", a);
16     printf("b = %d\n", b);
17 }
18 
19 void Demo()
20 {
21     printf("Demo:\n"); 
22 
23     const int& c = 1;    // 普通的引用int& c = 1; 编译器报错
24 
25     int* p = (int*)&c;
26 
27     //c = 5; 
28 
29     *p = 5;   
30 
31     printf("c = %d\n", c);
32 }
33 
34 int main(int argc, char *argv[])
35 {
36     Example();
37 
38     printf("\n");
39 
40     Demo();
41 
42     return 0;
43 }
引用的特殊意义

3. 对引用的思考

  引用有自己的存储空间吗?

 1 #include <stdio.h>
 2 
 3 struct TRef
 4 {
 5     char& r;
 6 };
 7 
 8 int main(int argc, char *argv[])
 9 { 
10     char c = 'c';
11 
12     char& rc = c;
13 
14     TRef ref = { c };
15     
16     printf("sizeof(char&) = %d\n", sizeof(char&));    // 1 char型变量的别名
17     printf("sizeof(rc) = %d\n", sizeof(rc));    // sizeof(c) => 1    变量c的别名
18 
19     printf("sizeof(TRef) = %d\n", sizeof(TRef));    // 4  结构体内的引用本质为指针,占4字节
20     printf("sizeof(ref.r) = %d\n", sizeof(ref.r));    // 1  char型变量的别名
21 
22     return 0;
23 }
引用的思考

4. 引用的本质

  (1)引用在C++ 中的内部实现是一个指针常量

  

  (2)C++ 编译器在编译过程中用指针常量作为引用的内部实现,将int& a 转换为int* const a因此引用所占用的空间大小与指针相同。

  (3)从使用的角度,引用只是一个别名,编译器使用引用时,会转为*aC++ 为了实用性而隐藏了引用的存储空间这一细节。

 1 #include <stdio.h>
 2 
 3 struct TRef
 4 {
 5     char* before; //4字节
 6     char& ref;//4字节,本质是常量指针,会分配4字节的空间,相当于char* const ref;
 7     char* after;//4字节
 8     
 9 };
10 
11 
12 int main()
13 {
14     char a = 'a';
15     char& b = a;
16     char c ='c';
17 
18     TRef r = {&a, b, &c};
19 
20     printf("sizeof(r) = %d\n", sizeof(r));               //12
21     printf("sizeof(r.before) = %d\n", sizeof(r.before)); //4
22     printf("sizeof(r.after)  = %d\n", sizeof(r.after));  //4
23     printf("&r.before = %p\n", &r.before);
24     printf("&r.after  = %p\n", &r.after); //after和before相差8个字节,中间隔了个b引用所占用的空间
25 
26     return 0;     
27 }
引用的存储空间

5. 引用的意义

  C++ 中的引用旨在大多数的情况下代替指针

  (1)功能性:可以满足多数需要使用指针的场合

  (2)安全性:可以避开由于指针操作不当而带来的内存错误

  (3)操作性:简单易用,又不失功能强大

 1 #include <stdio.h>
 2 
 3 int& demo()
 4 {
 5     int d = 0;
 6 
 7     printf("demo: d = %d\n", d); //输出0
 8 
 9     return d;//返回局部变量的引用,危险
10 }
11 
12 int& func()
13 {
14     static int s = 0;
15     printf("func: s = %d\n", s);//输出0
16 
17     return s; //合法,返回的是静态局部变量(位于全局存储区中的)
18 }
19 
20 
21 int main()
22 {
23     int& rd = demo();
24     int& rs = func();
25 
26     printf("\n");
27     printf("main: rd = %d\n", rd);//垃圾数值
28     printf("main: rs = %d\n", rs);//0,返回全局存储区中的s
29     printf("\n");
30 
31     return 0;     
32 }
函数返回引用

6. 小结

  (1)引用作为变量别名而存在旨在代替指针

  (2)const 引用可以使得变量具有只读属性

  (3)引用在编译器内部使用指针常量实现

  (4)引用的最终本质为指针

  (5)引用可以尽可能的避开内存错误

 

posted @ 2017-07-05 09:51  Hengs  阅读(325)  评论(0编辑  收藏  举报