浅析C++引用"&"
C++中引入了一个新的语言特性——引用(&),它表示某一对象的别名,对象与该对象的引用都是指向统一地址。那么我们就来看看关于引用的一些知识点吧🧐
特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用
- 引用仅能引用一个实体,不能再引用其他实体
用法
可以看出,引用与被引用的对象使用同一块空间
由此我们得出第一种用法,引用传参
在C语言中,交换函数需要使用指针获得地址,通过解引用形参达到修改实参的目的,这无疑是很麻烦的,而在C++中,只需要在接收参数时进行引用,就可以实现数据修改。
并且,由于引用指向的是同一地址,则在接收时不需要开辟栈区,所以当遇到大量数组传递时,引用可以提高运行效率
第二种,传引用返回
在C语言中,我们的传值返回是返回的临时变量,临时变量会存在寄存器中,或者提前开辟一段空间存储返回值,等返回后再销毁。而传引用返回则不会去开辟新的空间,直接将返回值所在的空间传回,这样也能够提高运行效率。
但是传引用返回是一种较为危险的行为,如下图:
当我们使用这种写法时,编译器会警告使用了临时变量的地址,原因是我们将返回值n给引用了,但n是个临时变量,出了作用域会销毁,此时根据编译器的不同,得到的结果也不同(有的编译器会暂时保存临时变量,直到该地址被再次使用,有的编译器会直接销毁,编译结果为随机值)
再来看下面这种写法,函数不变,但是将a给引用了,此时第一次打印没问题,第二次就变成了随机值,原因是第一次打印跟上面情况一样,编译器暂时保存了临时变量,但是第二次调用cout函数时,cout将count函数的空间覆盖了,取不到n的值,则被引用的a也变成了随机值!
由此得出,引用返回确实能提高运行效率,但是不要在返回局部变量时使用!可以在如下情况合理使用:
写一个简易的顺序表,用引用返回和引用传参可以实现读和修改并用的功能
常引用
来看下面的例子
第一个例子出错原因是a被const修饰成为静态常量,而b没有const,此时权限被放大了,正常情况下权限只能平移或者缩小,所以const int& b = a才是正确写法
第二个列子中,类型转换过程中会创建临时变量,临时变量具有常性,也属于权限放大,double前应加const修饰
第三个例子与第二个相同,该返回值是临时变量,具有常性,需要加const修饰
底层
引用的底层与指针一样,但是不能说引用就是指针
引用与指针
- 引用概念上是变量的别名,指针是存储一个变量的地址
- 引用在定义时必须初始化,指针没有要求
- 引用无法改变对象,指针可以改变对象
- sizeof中,引用为引用类型大小,而指针始终是地址空间所占字节个数
- 引用自加是对象+1,指针则是向后偏移一个类型的大小
- 没有多级引用
- 指针需要解引用才能取值,引用不需要
- 引用相对于指针更安全