IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C++入门篇】深入理解函数重载 -> 正文阅读

[C++知识库]【C++入门篇】深入理解函数重载

函数重载

函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数
形参列表(参数个数类型或顺序)必须不同,常用来处理实现功能类似数据类型不同的问题

 在C++中不仅函数可以重载,运算符也可以重载,例如:

 运算符<<,>>,既可以做移位运算符,也可以做输出,输入运算符,

*注意:重载函数的参数个数,参数类型或参数顺序三者中必须有一个不同*

  • 参数个数 类型 形参的顺序

函数重载例子

void func(int a, char c)  //1
{
	cout << "func(int a, char c)" << endl;
}

void func(char c,int a)	 //2
{
	cout << "func(char c,int a)" << endl;
}

void func(int a)			 //3
{
	cout << "func(int a)" << endl;
}
void func(double b,int a ,char c)  //4
{
	cout << "func(double b,int a ,char c)" << endl;
}
// 1 2 3 4 都是重载函数
int main()
{
    //我们在调用该函数时,函数会根据参数情况进行选择相应的函数.
	func(1, 'a');
	func('b', 1);
	func(1);
	func(3.14, 1, 'a');
	return 0;
}

image-20220912153344870


  • 返回值不同,但是形参相同 -> 不能构成重载函数 ->调用的时候不能进行区分
void func(int a)
{}

int func(int a)
{}

image-20220910231940288


  • 缺省值不同,不能构成重载
void func(int b = 2)
{}

void func(int a = 3)
{}

image-20220910231949443

重载和参数的名字无关

和参数个数 类型 形参的顺序有关


  • 形参是:无参和有参能构成重载,但空调用会产生歧义

image-20220910231957725

void func()
{
	cout << "func()" << endl;
}
void func(int a = 0)
{
	cout << "fuc(int a = 0)" << endl;
}
int main()
{
	//func();  产生歧义
	func(1);
 	return 0;
}

image-20220912153357628


总结:

  • 函数名称必须相同,
  • 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等),
  • 函数的返回类型可以相同也可以不相同,
  • 仅仅返回类型不同不足以成为函数的重载,

面试题:为什么C++支持函数重载,而C语言不支持函数重载呢?

程序编译过程

image-20220912153408101


image-20220912153414562


验证:C语言不支持函数重载

image-20220912153422598

->结果

image-20220912153433017

gcc 编译就是C语言 g++就是C++


屏蔽掉一个函数之后:

image-20220912153438786


若不屏蔽:使用C++编译:

image-20220912153443576


为什么C++支持重载呢

回顾程序执行的过程

在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接,

我们使用linux的gcc编译器对如下程序进行编译,以编译程序test.c为例:
gcc -E——预处理,生成的文件test.i
gcc -S——编译生成汇编代码,生成的文件为test.S
gcc -c——汇编生成机器码,生成的文件test.o

gcc——执行链接,生成默认名为a.out的可执行文件

image-20220912153513963


image-20220912153506894


有了函数声明,编译阶段就让过了,编译器会认为函数定义在其他地方,后续在链接时候,再去找它的定义

C++支持和C语言不支持重载,就是链接这个位置出的问题


C语言不支持函数重载,因为编译的时候,两个重载函数,函数名相同,在.o文件的符号表中存在歧义和冲突,其次在链接的时候也存在歧义和冲突,因为C语言查找函数是直接使用函数名取标识和查找,而重载函数,函数名相同

  • 语言查找函数是直接使用函数名取标识和查找

image-20220912153521988

在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变


若采用C++编译器g++编译后结果

image-20220912153530320

在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中,


g++的修饰函数名规则
_Z + 函数名长度 + 函数名 + 参数首字母

例如

void func(int a,int* p)
{}

image-20220912153535586

_Z + 函数名长度 + 函数名 + 参数首字母

_Z 4 func i pi (指针加前缀p)


而C语言对函数名的处理

直接使用函数名取标识和查找

image-20220912153542751

所以重载函数的函数名相同就不能通过了

C编译器直接用函数名关联,函数名相同时,它无法区别


C语言没办法支持重载,因为同名函数没办法区分,

而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载, 另外我们也可以看出,为什么函数重载要求参数(类型/顺序/个数)不同!而跟返回值没关系,

函数名相同,只要参数不同,修饰出来的名字就不同,就能区分了,就支持重载


image-20220912153552774


Windows下名字修饰规则

image-20220912153601377

函数重载的作用

重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处,


函数重载是一种静态多态:

(1)多态:用同一个东西表示不同的形态;
(2)多态分为:
静态多态(编译时的多态);
动态多态(运行时的多态);
(3)函数重载是一种静态多态;

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 10:54:41  更:2022-09-13 10:55:20 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/29 1:45:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码