在C++中,我们要学习一个新的概念,叫做引用。引用不是对象,它只是给变量取一个别名。就好比,我们每个人总会右一下外号,或者是小名。当朋友或者家长不管是直接叫你的名字,还是叫你的小名,你都会答应。
引用的概念和定义
引用不是定义一个新变量,而是给已存在的变量取一个别名,编译器不会为引用开辟空间,它和被引用变量使用的是同一块空间。
类型&引⽤别名=引⽤对象;
C++中为了避免引入太多复杂的符号,所以这里的引用符号和取地址符号&是同一个符号,只不过它们的用法不同,含义也不同。我们还是敲代码来看一看吧。
可以看到我们定义了一个变量a,我们使用b取引用它,现在b就是a的一个别名,然后们分别打印a,b 我们发现它们的值是相同的。下面我们再来看一看它们的地址是不是相同的呢?
可以看到它们两个都指向的同一块空间,自然都是同一个值。
一般在初始化变量时,初始值会被拷贝到新建的对象中。然而定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值拷贝给引用。一旦初始化完成,引用和它的初始值对象就一直绑定在一起。因为无法令引用绑定到另外一个对象,因此引用必须要初始化。
简单来说,引用在定义时就必须要初始化,然后它就无法改变引用对象了。
需要注意的是,引用本身不是一个对象,所以不能定义引用的引用。但是我们可以给别名取别名。
我们之后对引用进行操作也就是对它引用的对象进行操作。
通过代码可以看到,我们通过修改b的值,也修改了a的值。
引用的使用
引用在实践中主要用做引用传参和引用做返回值中减少拷贝提高效率和改变引用对象同时改变被引用对象。
比如我们使用函数交换两个数的值时,我们学习了C语言,首先想到的就是使用指针去交换两个值的大小。而当我们学习了C++中的引用后,我们就可以使用引用去交换两个变量的值了。
可以看到原来a=10,b=20,最后打印出的时候,a=20,b=10。说明两个变量的值已经得到了交换。 相比于以前使用指针去交换两个变量的值,我们使用引用就方便了许多。
后面我们还会学习到引用作为返回值的使用,我们后面再学习。
Const限定符
有时候我们希望定义这样一种变量,它的值不能被改变。所以我们用到了Const 限定符。根据它的中文翻译,它的意思是恒定的,不变的,无法修改的(const)。从而我们可以知道,当我们定义一个变量的时候,在它前面加上const可以防止它被修改。
初始化与const
对象的类型决定了其上的操作。与非const类型所能参与的操作相比,const类型的对象能完成很大一部分,但也不是所有的操作都适合。主要的限制就是只能在const类型的对象上执行不能改变其内容的操作。但是其它操作,比如:赋值,参与计算,转化成bool值等。
看 ,num已经被const修饰,我们尝试着去修改它,编译器给我们报错了,说表达式必须是可修改的左值。num本身是一个变量,但当我们使用const去修饰的时候,它就成为了一个常量,我们知道常量就是不能够修改的。
const的引用
可以把引用绑定到const对象上,就像绑定到其他的对象上一样,我们称之为常量引用。我们前面说过const可以让对象无法修改,可以理解为变成了常量。我们下面都用常量引用来说。
对于常量引用来说,需要记住的就是,只能小范围去引用大范围。
可以看到 num是一个常量,只能读取它。而我们想让一个可读可写的别名去引用它,这样就可能导致从rnum去修改到num,这是绝对不允许发生的。
我们再来看一看,当我们使用一个常量别名(只能读,不能修改)去引用num(能读,能写)着就是合法的。因为num是一个大范围,rnum是一个小范围。而上面那种情况就是大范围去引用小范围了就错了,就有点本末倒置的意思。人家本体都不能修改,你一个别名却想要修改它,这肯定是不被允许的。
常量指针和指针常量
与引用一样,也可以令指针指向常量或非常量。类似于常量引用**,指向常量的指针不能用于改变所指对象的值。**
我们还是通过代码来分析。
我们只需要记住,指针必须要和指向的对象类型相同。如上图,因为num的类型是const int 型,我们学习过指针,所以pnum2的类型就应该是const int * 型 。所以说我们称这样指向常量的指针为" 常量指针"。
下面我们来学习一下指针常量。顾名思义,指针就是一个常量,指针的值无法修改,那么它永远就只能指向一个对象了。
可以看到我们定义了两个变量,然后初始化的时候我们让pnum指向了num1,然后我们试图去修改pnum指向的空间,结果遭到了编译器的反对,报错,说指针是一个常量,无法修改。这就和前面的const修饰常量一样,类比一下,应该就很好理解。
最后还有一种指向常量的常量指针。也就是说该指针既不能修改指向的值,也不能修改它自己所指向的对象。 这句话听起来有点复杂,多理解一下就行了。
指针和引用的主要区别
在C++中,指针和引用都是用于处理内存地址的概念,但它们之间有一些重要的区别:
-
指针可以被重新赋值或者指向不同的内存地址,而引用在被初始化后就不能再引用其他对象,因此引用一般被认为是别名。
-
指针可以为空(nullptr),即不指向任何内存地址,而引用必须引用一个有效的对象。
-
指针使用"*"来访问保存在其指向地址中的值,而引用直接使用变量名来操作对象的值,因此引用操作起来更加方便。
-
指针可以指向空间被释放的内存地址(悬空指针),而引用则总是指向有效的对象,避免了悬空引用的情况。
总的来说,指针更加灵活,但使用引用可以在代码中更加清晰和直观地表达意图。在选择使用指针还是引用时,需要考虑代码的需求和设计,以及安全性和效率等因素。
欢迎大家点赞+评论。