C++引用传递基础

C++引用传递基础

 

引用变量:相当于是给变量内存块(内存单元)起别名

例如:

这里,我们存放整形变量10的内存单元名字为a,我们用过int &b = a; 让这个叫a的内存块有另外一个名字为b,从这里开始,a和b都指的是这个存放整形变量10的内存单元。

 

引用变量主要应用在函数的形参上,通过引用变量的使用,传递给函数的参数,就不是实参的副本了,可以直接通过修改形参,修改其本身的值。

 

一:引用变量的使用

我们使用上述的例子,看一看a和b指向的是不是同一块内存单元

我们这里可以看到,打印出来的a的地址和b的地址一样,可以证明a和b指向同一块内存单元。

 

数组的引用:

我们引用时,必须要将数组的长度传递进去。

 

二:引用变量在C++中底层处理方式

我们进入上述代码的反汇编中看一看:

这里,似乎和指针处理方式一致,都是将a内存单元的地址放到b内存单元中去。

 

我们在看一看指针在这里的处理方式,验证一番:

这里可以看到,指针和引用从底层处理来看,处理方式是一致的。

 

指针和引用不同点是:

①:指针会分配内存,用来存储指向的内存地址,可以通过*解引用的方式,找到指向的内存单元,自身开辟的内存单元也可以被找到。

②:而引用,虽然在C++中底层处理时和指针处理方式相同,不过在用到引用变量的地方,系统会自动对其进行解引用,这一步骤系统默认进行,所以我们找不到引用自身开辟的内存单元,从这里看,引用好像没有开辟自身内存,只是给引用对象起了一个别名。

 

 

三:使用引用变量时的注意事项

①:引用必须声明时就要有初始化

 

②引用初始化的变量一定要能取地址

我们从上述代码的反汇编可以看到,引用和指针处理方式相同,都是开辟空间保存指向内存的空间的地址,所以这个指向的内存空间一定要可以取地址!

例如这里的常量10就不可以引用,因为取不了地址。

 

我们可以对其进行修改,就是使用const关键字

我们进入反汇编可以看一看它是如何实现的:

 

我们可以看到,它是先申请了一个内存空间,将常量10赋值到这个内存空间中,再将这个内存空间的地址取出来,放到eax寄存器中,再申请一个内存空间,将eax寄存器中的值放入其中。

这里,我们可以得出结论:

通过const修饰的引用称作常引用,编译器首先会建立一个临时变量,将要引用的常量放入其中,这时,所引用的变量为编译器为其创建的临时变量。

在初始化常量引用时,允许用任意表达式作为初值,只要该表达式的结果能够转换成引用的类型即可。

 

 

③:引用是不可改变的

我们这里可以看到,我们本意是让b不再引用a,而是引用tmp,在修改b的值,本意是修改了tmp的值,可结果表示,tmp的值,没有修改,而a的值遭到了修改。

这里我们可以得出结论:引用不可中途改变,因为b还是引用a,还是作为a的别名存在,并没有改变。

 

 

四:引用和指针的区别

①:从内存分配上看,指针是实体,程序为其分配内存空间。而引用从表面上看,只是变量的别名,程序不需要为其分配空间。

②:引用使用时无需解引用(*),系统会为其自动进行解引用,而指针使用时需要手动解引用。

③:引用只能在定义时被初始化一次,之后则不可变。指针则可以改变。

④:引用不能为空,指针可以为空。

⑤:“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身(所指向的变量或对象的地址)的大小;

⑥: 指针和引用的自增(++)运算意义不一样;指针自增是让其指向下一段内存单元,而引用自增是使其对应的变量自增。

 

 

五:引用作为参数

我们这里将引用作为参数和值传递进行比较。

 

普通变量作参数:典型值传递,无法修改实参的值。

我们可以看到,a和b的值并没有进行交换。

 

我们再用引用变量做参数:引用传递,可以修改实参的值。

我们可以看到,a和b的值进行了交换。

 

猜你喜欢

转载自blog.csdn.net/IT_Quanwudi/article/details/84549968