函数的重载、引用——初识C++(2)

4.函数的重载

4.1 函数重载的概念

C语言中,我们不能定义两个同名的函数。
而在C++中允许定义同名函数,但这些函数的参数要有所区别,这样的同名函数就构成了函数重载。
在这里插入图片描述
这里的参数不同指的是:
1.参数类型不同
2.参数个数不同
3.参数顺序不同(本质上是类型不同);

4.2 C++支持函数重载的原因

简绍完函数重载;那在声明与定义分离的情形中,编译时,编译器是如何区分两个函数名相同的函数的呢?
C++给出了他的答案:C++并不像C语言那样直接用函数名去找函数的地址,它增加了函数名的修饰规则,函数名中引入了参数的类型。当然各种不同的编译器有自己的一套实现规则。下面我们用VS的规则进行说明:
在这里插入图片描述

5.引用(十分重要)

引用是C++中新增加的语法,他的出现与我们C语言阶段学习的指针共同协作能实现很多便捷的功能,因此它在C++中有着举足轻重的地位。

5.1 引用的概念

那引用究竟指什么呢?
我们不妨从生活场景切入:生活中,父母给你起了一个小名 a;学校中,同学给你起了一个小名叫做 b;此时父母叫a,同学叫b,其他人叫你的本名——这三种情况都是叫你本人。父母同学给你取的小名就是C++中说的引用
引用:引用就是给已存在的变量取了一个别名
语法规则:int a=0;int& ra=a; //ra 是 a 的引用(ra 是 a 的别名)
在这里插入图片描述
由上图可看出,引用类型并不会另外开空间,它和它的引用的变量都共用一块内存空间,我们就可以具象的理解为取别名

5.2 引用的特性

了解了什么是引用,那如何正确的使用引用呢?
下面,我们会介绍引用的一些特性:
1.引用在定义时必须初始化(也就是起别名时就要明确对象是谁,引用与引用对象之间存在一个因果关系);
在这里插入图片描述
2.引用不能改变其引用对象(一旦确定别名,这个别名仅限于一个人用)

在这里插入图片描述
运行过后我们发现:a,b,c都变成2了!!!,说明b=c在这里是赋值,并不能改变b的引用对象!!!
在这里插入图片描述
3.一个变量可以有多个引用(一个人可有多个别名)
在这里插入图片描述

5.3 引用的应用场景

我们已经认识了引用,是否发现它与指针有着异曲同工之妙?那竟然已经有了指针威慑么还要有它呢?那当然是因为引用在一些场景的使用更加方便,下面我们就来具体看看引用的实际运用场景

5.3(1)做参数

我们写来例举一个十分简单的场景:
我们写交换两个数的函数时常用指针来传值:

void Swap(int* x,int* y)
{
	int tep = *x;
	*x =*y;
	*y = tep; 
}

那当我们学习了引用,以上代码可以改写为:

void Swap(int& x,int& y)
{
	int tep = x;
	x = y;
	y = tep; 
}

诶,我们发现运用引用之后我们不用传地址过去就能交换两个数了!!!!
有了这个简单的例子,大家是否能想起之前我们学习单链表时(头插)需要改变头结点的指针,我们总是要传二级指针:

void SLPushFront(SLNode** pphead,SLDatetype x)
{
	assert(pphead);
	SLNode* node = SLBuyNode(x);
	node->next = *pphead;
	*pphead = node;
}

学习了引用之后,我们直接传指针的引用别名)即可,不用再传二级指针,极大的简化了代码理解难度与书写难度:

void SLPushFront(SLNode*& phead,SLDatetype x)
{
	assert(phead);
	SLNode* node = SLBuyNode(x);
	node->next = phead;
	phead = node;
}

在引用做参数的同时,若参数比较大还能够减少拷贝,提高效率:在这里插入图片描述

到这我相信大家已经体会到C++中引用的好处,我们能妥善利用引用与指针这两大工具,能大大方便了我们日常编程。当然由于C++中引用不能修改引用对象这一特点,有些特定的情况我们只能利用指针(例如双向链表我们需要改变指向时就不能用引用了)。

5.3(2)做返回值

我们继续来看下一个场景——我们要写一个函数将函数内部的值返回:
在这里插入图片描述
我们返回的值并不是 a 本身,因为当函数调用结束时,a 的生命周期已经结束,我们可以再来回忆一下函数栈帧的创建与销毁:函数值是通过寄存器从函数中带回main函数中的。
在这里插入图片描述
而当我们使用了引用当返回值呢?在这里插入图片描述
若返回a的引用代表返回的是a所在空间本身的值不再寄存机存储临时变量带回值,而此时a所在空间已经被销毁,内部可能为随机值不再是0!!!!!是错误的用法。在这里插入图片描述
甚至返回接收值若都为引用,则更能验证上述操作的错误性,这就是经典的野引用在这里插入图片描述

结论:1.传值返回的是变量的一份拷贝,传引用返回返回的是变量本身的值
2.如果返回的变量出了函数生命周期结束,此时不能使用引用返回必须传值返回
那哪些只可以使用引用返回呢?
1.全局变量
2.静态变量
3.堆区空间等等…
引用做返回值的正确案例我们后续类和对象章节会反复遇到,此处不再具体举例。同时用引用做返回值和做参数一样也能提高效率,此处也不再详细赘述。

5.4 引用与指针

5.4(1)引用的语法与底层区别

语法层面:引用只是别名不开多余空间和引用实体用同一块空间
那实际上呢?这就不得不看看引用的底层了:在这里插入图片描述
因此
底层方面:引用底层需要开辟空间的因为引用是按照指针来实现的

5.4(2)引用与指针的区别

1.在语法层面,引用仅仅为别名不开空间;而指针是地址需要开空间
2.引用使用时必须初始化;而指针没特殊要求(可初始化也可不初始化)
3.引用不可改变其引用实体(对象);而指针则可在需要的时候改变其指向空间
4.引用没有空引用,而且不易出现野引用;指针有空指针,容易出现野指针,相对指针,引用更安全
5.在sizeof中的区别:引用是引用的数据类型的大小;指针是地址空间所占字节数
6.引用自加是实体自加;二指针自加指向后偏移
7.无多级引用;但存在多级指针

5.5 常引用

在日常使用引用中,如果我们不希望引用去修改实体;此时就需要常引用来对引用进行修饰:

const int&

当对引用加上const修饰表示不能修改实体的引用,这实际上是一种权限的缩小;实际上引用的权限能缩小但绝对不能放大,如下就是对引用权利的放大:在这里插入图片描述
在这里插入图片描述
我们知道以上这些性质,我们未来函数传引用参数时用const修时候便能传递表达式与常量:在这里插入图片描述
在这里插入图片描述
同理:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值