第5课 引用的本质分析

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

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

swap函数的实现对比如下:

注意:

  函数中的引用形参不需要进行初始化。

示例程序如下:

形参没有初始化,而是在第15行调用的时候对引用形参进行初始化。

const引用:

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

例:

结论:

  使用常量对const引用初始化后将生成一个只读变量。普通引用不能使用常量值进行初始化,但是const引用可以。

我们不能直接改变const引用的值,但是可以通过取地址的方式间接的改变这块内存的值。

示例程序:

 1 #include <stdio.h>
 2
 3 void Example()
 4 {
 5     printf("Example:\n");
 6
 7     int a = 4;
 8     const int& b = a;
 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;
24     int* p = (int*)&c;
25
26     //c = 5;
27
28     *p = 5;
29
30     printf("c = %d\n", c);
31 }
32
33 int main(int argc, char *argv[])
34 {
35     Example();
36
37     printf("\n");
38
39     Demo();
40
41     return 0;
42 }

运行结果如下:

  可以看到Example函数中通过指针p可以改变内存空间的值,最终影响到了a和b的值,其实它们指的是同一块内存空间,在这个函数中我们也可以直接改变a的值。因为a并不是const的。

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

示例程序如下:

 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     char& rc = c;
12     TRef ref = { c };
13
14     printf("sizeof(char&) = %d\n", sizeof(char&));
15     printf("sizeof(rc) = %d\n", sizeof(rc));
16
17     printf("sizeof(TRef) = %d\n", sizeof(TRef));
18     printf("sizeof(ref.r) = %d\n", sizeof(ref.r));
19
20     return 0;
21 }

执行结果:

char&代表char的引用,所以占用一个字节,rc也是char的引用,占用一个字节,ref.r是char的引用,也占用一个字节。

sizeof(TRef)占用四个字节,这让我们联想到了指针。

引用的内部实现:引用在C++中的内部实现是一个指针常量,具体如下。

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9515093.html

时间: 2024-10-09 23:48:01

第5课 引用的本质分析的相关文章

第27课 数组的本质分析

1. 数组的概念 (1)数组是相同类型的变量的有序集合 (2)数组在一片连续的内存空间中存储元素 (3)数组元素的个数可以显示或隐式指定 [编程实验]数组的初始化 #include <stdio.h> int main(){ //数组初始化 int a[5] = {1, 2};//第1.2个元素分别为1.2,其余为0 int b[] = {1, 2};//编译过程中,编译会为计算数组b的大小 int i=0; for (i = 0;i < 4;i++) { printf("a[

C++中引用的本质分析

引用的意义 引用作为变量别名而存在,因此在一些场合可以代替指针 引用相对于指针来说具有更好的可读性和实用性 swap函数的实现对比: void swap(int* a, int* b) { int t = *a; *a = *b; *b = t; } void swap_yinyong(int& a,int& b) { int t = a; a = b; b = t; } int main() { int a = 1; int b = 2; printf("a = %d,b =

第51课 继承对象模型分析——多态的本质分析

多态的本质分析 用C写面向对象,用C实现多态 #ifndef _51_2_H_ #define _51_2_H_ typedef void Demo; typedef void Derived; Demo* Demo_Create(int i, int j); int Demo_GetI(Demo* pThis); int Demo_GetJ(Demo* pThis); int Demo_Add(Demo* pThis, int value); void Demo_Free(Demo* pThi

C++引用的本质——另一种指针

本文不探讨罗列引用的概念,什么函数传参之类的,这些基础概念和用法很容易搜到-! 本文主要探讨引用和指针在C语言的下一层--即汇编或者确切的说是伪汇编(AT&T伪汇编都一样的代码,你指望下层x86汇编还能不一样么-)--的实现过程,来摸索一下他们的特点与本质. 首先,引用(Reference)在C中没有,是C++ 才有的概念-! 要用g++编译器. 定义:引用就是某个目标变量的"别名"(alias) 在我看来,这个"目标变量"也要加上引号,看"目标变

C/C++指针的指针(**p)和指针的引用(*&amp;)使用案例分析

#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> int func1(int *a) { a = new int; *a = 1; printf("func1 addr a=%p\n",a); return *a; } int func2(int **a) { *a = new int; **a = 10; //如果是指针的指针,那函

第39课 逗号操作符的分析

1. 逗号操作符 (1)逗号表达式用于将多个子表达式连接为一个表达式 (2)逗号表达式的值为最后一个子表达式的值 (3)逗号表达式的前N-1个子表达式可以没有返回值 (4)逗号表达式按照从左向右的顺序计算每个子表达式的值 exp1,exp2,exp3,…,expN; [实例分析]逗号表达式的示例 #include <iostream> using namespace std; void func(int i) { cout << "func(): i = " &

C++学习笔记----2.4 C++引用在本质上是什么,它和指针到底有什么区别

从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变. 而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量). 在C++中,指针和引用经常用于函数的参数传递,然而,指针传递参数和引用传递参数是有本质上的不同的: 指针传递参数本质上是值传递的方式,它所传递的是一个地址值.值传递过程中,被调

第28课 指针和数组分析(上)

1. 数组的本质 (1)数组是一段连续的内存空间 (2)数组的空间大小:sizeof(array_type)*array_size; (3)数组名可看做指向数组第一个元素的常量指针 [编程实验]a + 1的结果是什么?  (答案是第2个元素的地址) #include <stdio.h> int main(){ //将数组每个元素初始化为0 int a[5] = {0}; int* p = NULL; printf("a = 0x%X\n",(unsigned int)(a)

C++ 之 第十课 引用篇

引用的介绍 什么是引用?引用就是别名,别名就是创建一个对象的另一个名称.创建引用的方法用&符号.在c++ 下你可以把它看作是另外的一种指针,通过引用类型我们同样也可以间接的操作对象,引用类型主要是用在函数的形式参数上,通常我们使用它是把类对象传递给一个函数. 引用对象采用类型名加上&符号和名称的方式进行定义.例如:(int &test;),这里我们就定义了一个int类型的名为test 的引用,但是int &test;这样的方式是不能够被编译成功的,因为引用的定义必须同时给应