“引用”,是C++提出的一种全新的形式,作为一种新的语法形式,“引用”为程序员的编程提供了便利,最明显地好处,我们可以不用指针就能修改一个变量的值。 看过很多的教材,在“引用”这一节中,都没有对“引用”的实现进行详细的阐述,教材大多是对于“引用”的概念以及用法进行了阐述,这样不利于同学深刻掌握“引用”,在计算机中,任何我们看起来理所应当的东西,在背后,都是需要一套机制来实现的,因此,本文决心探讨C++中“引用”的底层实现。 这里,我们用int类型的引用来阐述问题,探讨“底层”实现,就会不可避免的用到汇编语言,先看代码,如下: int a = 2; int &r = a; r = 5; 定义一个整型变量a、初始化为2,定义了a的引用r,并且通过引用为a重新赋值。 反汇编后,得如下: 对于上面的汇编指令,同学们可能不理解,先说红色方框内的指令,咱们用C语言来解释说明,也就是,如下: int *r = &a; 从汇编指令的角度来看,r是指向变量a的指针,在编程语言层面,我们可以理解为“r和a相同,r是a的另一个名字”,其实这样理解是多少是有问题的,为何这么说? 如上的汇编指令所示,虽然说r作为a的引用,但是实际上,r和a是不同的,r是指向a的指针,我们不能将r简单理解为a的别名,如果将r理解为a的别名,那么r也就是不会占据内存空间的,但是实际上,r在栈上会占据内存空间的。 继续说蓝色方框里面的指令,咱们接着用C语言来解释说明,也就是: *r = 5; 咱们可以连起来看了,如下: int a = 2; int &r = a; r = 5; 这三行代码,在汇编语言层面,其真实作用效果类似于如下代码: int a = 2; int*r = &a; *r = 5; 现在,我们可以得出结论,C++中的“引用”在底层是靠指针来实现的。 说到这里,不免要说到引用作为形式参数的情况了,如上所示,引用作为函数的形式参数,在进行函数调用时,在汇编语言层面,也是将实际参数的地址传递给了形式参数,这个指针作为形式参数没有太大的区别。 既然指针和引用有诸多的相似点,那么C++为何还要引入“引用”呢? 不知道大家有没有考虑过这种情况,我们对函数的返回值进行赋值,即我们写成如下的形式: f() = 5; 在“引用”出现之前,这种写法,是不合法的,因为函数的返回值是一个“值”,也就是一个右值,我们无法对右值进行赋值。 “引用”的出现,改变了这种情况,我们可以对函数的返回值进行赋值,看代码: “引用”作为函数的返回值,本质上是一个左值,我们可以对它进行赋值操作,“引用”的主要应用场景是运算符重载,在实现一些运算符的重载时,必须要让函数的返回值为左值,如赋值运算符(=)重载,这个时候,就得用“引用”了。 “引用”是C++引入的新的语法,希望大家不仅能知其然,也能知其所以然。 想要一起学习C++的可以加群248894430,群内有各种资料满足大家 |
|