C++基础 引用

引用

定义

引用不是新定义一个变量,而是给已存在变量取了一个别名(语法层面),编译器不会为引用变量开辟新的内存空间,引用和引用的变量共用同一块内存空间

注意:引用类型必须和引用实体是同种数据类型

语法

数据类型& 引用名(对象名)=引用实体变量;

使用示例

#include <iostream>
using namespace std;

void TestRedef() {
	int a = 100;
	int& ia = a;//引用
	int* pa = &a;//指针
	cout << "TestRedef():";
	cout << &a << " " << &ia <<" " << pa << endl;
	cout << a << " " << ia <<" "<< *pa << endl;
	//验证引用和引用实体共用同一块内存空间
}

void TestRedef(int& a, int b) {
	a = 101;
	b = 200;
	cout << "TestRedef(int& a,int b):";
	cout << &a << " " << &b << endl;
	//对比引用和非引用在函数参数上的差别
}

int main() {
	int a = 0, b = 1;
	TestRedef();
	TestRedef(a, b);
	cout << &a << " " << &b << endl;

	return 0;
}

输出结果:
引用的使用

特性

1. 引用在定义时必须初始化

引用初始化的必要性

2. 一个变量可以有多个引用

一个变量可以有多个引用

3. 引用一旦引用一个实体,便再不能引用其他实体(从一而终,与指针进行对比)

引用只能引用一个实体

这样的语句意义属于赋值而无法再次引用

常见使用场景

1. 引用作为函数参数(代替指针)

传指针与传引用对比
传指针与传引用对比输出结果
引用作为函数参数

注意:传值,传地址和传引用三者可以构成函数重载,
然而,虽然传值与传引用可以构成重载,但在调用时会产生冲突(歧义)

传值与传引用

不调用
调用

特例:指针的引用代替二级指针

单链表为例
结构体
创建结点
增添元素
辅助测试函数main内容

输出结果
使用二级指针的输出结果

观察可知,在增添元素时,需要通过传二级指针以修改一级指针的指向,也就是修改二级指针存储的内容
在C++中,通过指针的引用,也可以实现修改一级指针的指向

修改为指针的引用的函数声明
修改为指针的引用的函数定义
main内容

输出结果不变
使用指针的引用输出结果

2. 引用作为函数返回值

调用函数的临时变量存储
如果临时变量较小,一般是寄存器充当临时变量
如果临时变量较大,则会放在调用函数的栈帧中。

引用作为函数返回值

注意:能否使用引用作为函数返回值取决于返回对象的生存期.
函数返回时离开函数作用域,如果返回对象还未还给系统(静态变量),
则可以使用引用返回;
如果已经销毁(局部变量),则必须使用传值返回函数值

static修饰的cnt相当于全局变量,生存期相对局部变量延长,此时函数返回类型是否引用不会构成影响

传值

传值生成的是局部变量的拷贝值

传引用

引用返回的含义是:不生成临时变量的拷贝值,直接返回原变量的别名,近乎等价于直接返回原变量,一旦函数栈帧已销毁,通过引用会造成非法访问,此时取值取决于编译器实现并且随机不定

因此,一般过程不要轻易使用引用返回!!!

但是,在面向对象编程中,使用引用返回值具有重要意义

引用的价值

引用的存在可以解决指针的复杂性问题, 通过引用使部分场景简化;
通过不重复拷贝而提升效率和性能

1.作为参数

提高传参效率; 创造输出型参数(形参的修改可以影响实参)

2.作为函数返回值

简单场景下一般不使用引用作为返回值;
合适情景下使用可以提高效率,修改返回变量;
在参数或返回值类型较大(大对象+深拷贝对象)时,通过引用返回可以提升性能

引用的性能效率

1.传参性能对比(传引用较为自由)

头文件

传参性能对比

2.返回性能对比(传引用使用受到限制)

返回性能对比

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
在底层实现上实际是有空间的,因为引用的底层实质是按照指针方式来实现的。

引用和指针的区别

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址
  2. 引用在定义时必须初始化,指针最好初始化,但是不初始化也不会报错
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型
    实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

总结:指针使用起来更复杂一些,更容易出错一些

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值