文章目录
- 函数重载
- 什么是函数重载?
- 函数重载的作用
- 使用函数重载的注意点
- 为什么C++可以函数重载,C语言不行?
- 引用
- 什么是引用?
- 引用的语法
- 引用的特点
- 引用的使用场景
- 引用的底层实现
- 传参时传引用和传值的效率
- 引用和指针的区别
函数重载
什么是函数重载?
函数重载:
重载函数是函数的一种特殊情况。
为方便使用,C++允许在同一作用域中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指1.参数的个数 2.类型 3.顺序)必须至少有一个不同
根据这些同名函数的参数表的不同,达成传入参数类型不同,调用的函数不同的效果
函数重载的作用
让功能类似
的函数可以用同一名字,不用费心思去取差别不大的名字
例
如果不用函数重载,就要给Swap,取Swap1,Swap2等名字容易混淆
使用函数重载的注意点
-
函数重载与函数的返回值
无关
-
同名
且参数表不同
【参数表不同即参数类型不同或参数个数不同或参数顺序不同(满足三个条件中的一个就行
)】的函数就可以构成重载
参数类型不同:
参数个数不同:
参数顺序不同:
-
只有
同一作用域
中的同名
且参数表不同
函数才构成重载
即不同命名空间/类
中的同名函数不可能
构成重载 -
重载函数也
可以参数缺省
例
这个时候就要注意:不要因为少传参数
而导致调用的重载函数不明确
例
为什么C++可以函数重载,C语言不行?
这就又涉及到编译链接
了,因为C++是在C语言的基础上出现的,而且C++是兼容C语言的【即C语言的语法在C++编译器中也能使用】所以C++的编译链接过程和C语言很像
(不了解编译和链接的可以看我这篇文章:c语言编译和链接)
为什么C++可以函数重载,C语言不行?这一问题主要是在编译链接时的编译
和汇编
时的符号汇总
和形成符号表
【符号表:可以简单的将其视为 词法分析
时拆分出来的所有特殊符号
+该特殊符号对应的地址
共同制作出的一份方便链接
的表】的时候
C语言编译链接时函数名进入符号表时表中对应的特殊字符就是它的函数名
【不做任何修饰】
而C++的函数进入符号表时表中对应的特殊字符是编译器根据该函数的参数表
和编译器自己的修饰规则
【每个编译器的修饰规则不同】对该函数名进行修饰之后的特殊符号,而不是单纯的函数名
上面的差异就在编译链接的链接部分起了不同的作用
因为链接是根据符号表中的特殊符号的名字找它的地址,并以此看它有没有定义
而C语言如果函数名同名了,那进入符号表的都是它的函数名根本区分不开,就算两个函数都有定义有地址,链接时编译器根本不知道找那个。
但C++不同它进入符号的是编译器根据该函数的参数表
和编译器自己的修饰规则
修饰之后的符号,如果它的参数不同修饰后的符号就不同,链接时编译器“一眼“就看出不同了
引用
什么是引用?
引用是给已存在变量取一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
即使用一个变量的引用就是使用该变量,修改它的引用
也是修改变量自己
例
引用的语法
源变量的类型+&+别名=源变量名
例
引用的特点
-
引用
必须初始化
-
一个变量可以有多个引用
例
-
引用一旦引用一个实体后就
不能
去引用其他实体了
例
如果直接=,就是赋值
引用的使用场景
引用可以做参数,可以达到类似指针的效果
例
这样设计Swap的参数的话,形参a,b就是实参a,c的引用,那么该a,b就是改a,c,改形参就是改实参
引用的底层实现
引用的底层【汇编层次
】实现其实是和指针一样的
都是开出一个指针大小的空间将引用(指向)的变量的地址放进去
但是使用上却不同,为什么呢?
其实是编译器进行了隐式的包装,我们使用引用时使用到的就是那一层包装
所以一般认为:
引用语法上
是不开空间的,引用和它引用的源变量共用一个空间
指针语法上
是开空间的,将指向的对象的地址存入开出的空间
传参时传引用和传值的效率
传引用效率更高,因为引用底层实现是和指针一样的,开空间存地址
所以传参时,如果形参是引用,那么实参传递的其实是实参的地址
引用和指针的区别
-
引用概念上定义一个变量的别名,指针存储一个变量地址。
-
引用在定义时必须初始化,指针没有要求
-
引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
-
有多级指针,但是没有多级引用
-
没有NULL引用,但有NULL指针
-
引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
-
访问实体方式不同,指针需要显式解引用,引用编译器自己处理