目录
1. 引用的定义
2. 引用的本质
3. 引用的意义
4. 特殊的引用 - const 引用
5. 引用和指针的关系
1. 引用的定义
C++ 新增加了引用的概念:
引用可以看作一个已定义变量的别名
引用的语法 Type &name = var;
- int a = 4;
- int &b = a; //b 为 a 的别名
- b = 5; // 操作 b 就是操作 a
2. 引用的本质
引用在 C++ 中的内部实现是一个常量指针
Type &name <==> Type *const name
C++ 编译器在编译过程中使用常量指针作为引用的内部实现, 因此引用所占用的内存大小和指针相同
从使用的角度, 引用只是一个别名, C++ 为了实用性而隐藏了引用的存储空间这一细节
- #include <cstdio>
- struct TRef
- {
- char &r;
- };
- int main(int argc, char *argv[])
- {
- char c = 'c';
- char &rc = c;
- TRef ref = { c };
- printf("sizeof(rc) = %d\n", sizeof(rc));
- printf("sizeof(TRef) = %d\n", sizeof(TRef));
- printf("sizeof(ref) = %d\n", sizeof(ref));
- printf("sizeof(ref.r) = %d\n", sizeof(ref.r));
- /*sizeof(type &) 的大小, 就是 type 类型的大小 */
- printf("sizeof(char &) = %d\n", sizeof(char &));
- printf("sizeof(int &) = %d\n", sizeof(int &));
- printf("sizeof(double &) = %d\n", sizeof(double &));
- return 0;
- }
- #include <stdio.h>
- struct TRef
- {
- char *before;
- char &ref;
- char *after;
- };
- int main(int argc, char *argv[])
- {
- char a = 'a';
- char &b = a;
- char c = 'c';
- TRef r = {&a, b, &c};
- printf("sizeof(r) = %d\n", sizeof(r));
- printf("sizeof(r.before) = %d\n", sizeof(r.before));
- printf("sizeof(r.after) = %d\n", sizeof(r.after));
- printf("&r.before = %p\n", &r.before);
- printf("&r.after = %p\n", &r.after);
- return 0;
- }
3. 引用的意义
C++ 中的引用作为变量别名而存在, 旨在大多数的情况下代替指针
引用可以满足绝大多数需要使用指针的场合
引用可以避开由于指针操作不当而带来的内存错误
引用相对于指针来说具有更好的可读性和实用性
注意: 由于引用的内部实现为指针, 因此函数不能返回非静态局部变量的引用
- #include <stdio.h>
- int &demo()
- {
- int d = 0;
- printf("demo: d = %d\n", d);
- return d;
- }
- int &func()
- {
- static int s = 0;
- printf("func: s = %d\n", s);
- return s;
- }
- int main(int argc, char *argv[])
- {
- int &rd = demo();
- int &rs = func();
- printf("\n");
- printf("main: rd = %d\n", rd);
- printf("main: rs = %d\n", rs);
- printf("\n");
- rd = 10;
- rs = 11;
- demo();
- func();
- printf("\n");
- printf("main: rd = %d\n", rd);
- printf("main: rs = %d\n", rs);
- printf("\n");
- return 0;
- }
4. 特殊的引用 - const 引用
在 C++ 中可以声明 const 引用
const Type &name = var
可以使用 const 常量, 变量, 字面值常量对 const 引用初始化
不管使用何种方式初始化, const 引用都将产生一个只读变量
当使用字面值常量对 const 引用初始化时, C++ 编译器会为常量值分配内存空间, 并将引用作为这段内存空间的别名
const 引用类型 VS 初始化变量类型
类型相同, const 引用的就是初始化变量
类型不同, const 引用的不是初始化变量, 而是初始化变量的临时对象
注意: const 只是修饰符, 不代表类型, 也就是说, const int 和 int 是相同类型.
- #include <stdio.h>
- int main()
- {
- const int a = 3;
- int b = 4;
- char c = 'c';
- const int &ra = a;
- const int &rb = b;
- const int &rc = c;
- const int &rd = 1;
- int *p1 = (int *)&ra;
- int *p2 = (int *)&rb;
- int *p3 = (int *)&rc;
- int *p4 = (int *)&rd;
- *p1 = 5;
- *p2 = 6;
- *p3 = 7;
- *p4 = 8;
- printf("ra = %d\n", ra);
- printf("rb = %d\n", rb);
- printf("rc = %d\n", rc);
- printf("rd = %d\n", rd);
- printf("\n");
- printf("b = %d\n", b); //b 的类型和 rb 相同, rb 引用的就是 b, 所以改变 rb 的值, b 也跟着一起改变
- printf("c = %c\n", c); //c 的类型和 rc 不同, rb 引用的是 c 的临时对象, 所以改变 rc 的值, c 不受影响
- return 0;
- }
5. 引用和指针的关系
指针 | 引用 |
---|---|
指针是一个变量,其值为一个内存地址 | 引用是一个变量的新名字 |
指针可以不初始化, 而是在使用时赋值 | 引用必须在定义时初始化 |
通过指针可以访问对应内存地址中的值 | 对引用的操作(赋值、取地址等)会传递到代表的变量上 |
指针可以保存不同的地址 | 引用在初始化之后无法代表其他变量 |
指针可以被 < font color="blue" ztid="127" ow="39" oh="17">const 修饰,成为 < font color="magenta" ztid="128" ow="28" oh="17">常量 或 < font color="magenta" ztid="129" ow="56" oh="17"> 只读变量 | const 引用 使其代表的 < font color="blue" ztid="132" ow="112" oh="17"> 变量具有只读属性 |
在工程项目开发中
当进行 C++ 编程时, 直接站在使用的角度, 引用和指针没有任何关系
当对 C++ 代码进行调试分析时, 一些特殊情况, 可以考虑站在 C++ 编译器的角度, 引用在内部实现为指针常量
我们给出一个站在 C++ 编译器的角度看待引用的示例, 下面这段代码有问题吗?
- int a = 1;
- int b = 2;
- int *pc = new int(3);
- int &array[] = {
- a, b, *pc
- };
数组是一片连续的内存空间
引用数组会破坏该特性, 各元素代表的变量可能存储在不同的位置
因此, C++ 不支持引用数组!!!!!!
- #include <stdio.h>
- int a = 1;
- struct SV
- {
- int &x;
- int &y;
- int &z;
- };
- int main()
- {
- int b = 2;
- int *c = new int(3);
- SV sv = {a, b, *c};
- int &array[] = {a, b, *c}; //&array[1] - &array[0] != 4, 编译报错
- printf("&sv.x = %p\n", &sv.x);
- printf("&sv.y = %p\n", &sv.y);
- printf("&sv.z = %p\n", &sv.z);
- delete c;
- return 0;
- }
首先, 注释掉代码第 17 行, 编译运行结果如下, 可以看出打印出的内存地址是各不相同的.
然后, 去除代码第 17 行注释, 结果编译报错, 原因就是数组的三个元素地址不连续, 而是各不相同.
来源: https://www.cnblogs.com/songhe364826110/p/11518880.html