本篇文章我们要深入理解函数重载。还不了解函数重载的小伙伴可以看看上篇文章末尾简单理解一下[C++] helloworld 解析 C++入门(一)
本篇主要解决的问题:
1.C语言不支持重载,C++支持重载,为什么?
2.C++如何支持重载?
目录
问题的引入
首先我们复习一下函数重载。函数重载就像是一词多义,一个函数名可以有多个意思。函数可以根据参数的不同选择进入不同参数的函数。
那么,这种情况属于函数重载吗?
short Add(short left, short right)
{
}
int Add(short left, short right)
{
}
答:这种是不构成函数重载的,这是因为函数重载跟返回值没有关系,在VS2019下编译器也会主动报错。
那么今天我们就是来底层深挖,为什么和返回值没有关系,又为什么和参数的顺序,个数,类型有关系呢?
1.函数重载(C++)
在我们学习C语言的过程中我们知道编译链接的过程,为了更好的展示这个过程,我们使用Linux来看这段过程。
1.1编译链接过程
首先我们复习一下编译连接的过程:
1、预处理 — 头文件展开,宏替换,条件编译,去掉注释
f.i test.i
2、编译 — 检查语法,生成汇编代码
f.s test.s
3、汇编 — 把汇编代码转换成二进制的机器码
f.o test.o
4、链接 — 找调用函数的地址,链接对应上,合并到一起 合并符号表
a.out
1.1.1预处理
在预处理的过程中,会进行头文件的展开,宏替换,条件编译,去掉注释等一些操作,这个过程非常的重要。在这里我们重点说说头文件展开。
头文件展开:
假设现在我们创建一个f.h的头文件,f.cpp的文件。
那么头文件的展开就是将f.cpp的头文件进行展开。如下图所示:
此时的cpp文件为:
经过预处理的过程,我们在编译的过程中我们就可以找到函数了。
1.1.2编译
检查语法,生成汇编代码,汇编代码是一种指令级的语言,如果有语法错误,就会在这个阶段出现。
我们在VS下看看什么是指令级的代码,这些指令级的代码是给CPU准备的,CPU是执行指令的。
例如:我们看看最简单的helloworld的指令代码
1.1.3汇编
当语法没问题的时候,我们就来到了汇编,此时这个指令级代码CPU不认识,机器都只认识0和1。因此汇编的过程就是将汇编代码转换成二进制的机器码。
1.1.4链接
找调用函数的地址,链接对应上合并到一起,合并符号表。
我们来理解一下这个过程:
这预处理过程中头文件展开如下
在编译的过程中还会生成一个符号表,主要记录函数定义和函数地址的映射,那符号表为什么要生成函数地址的映射呢。此时我们来看
在main函数的指令中,有两句指令call,call后面所跟的就是函数的地址,函数的名字和函数的地址。然后我们来看一下这个过程,真正的函数地址就是第一句指令的地址。函数的名字也会有自己的命名规则。
为了更好的看函数的命名规则,我们在linux下看看这个细节。当函数名相同,参数不同时,他们的函数名会有一套新的命名规则。在不同的话函数调用中,他们参数类型首字符带进命名规则中去了。
新的函数名:_Z 函数名长度 函数名 类型首字母
因此即使函数名相同,但参数的类型不同,顺序不同,个数不同都会产生不同新的函数名。
因此再调用的时候对应的名字是不相同的。因此所对应的地址也是不同的
这也是为什么C++支持函数重载的原因。
2.C语言中处理
那我们在C语言中再看看这个过程,他的新的函数名是怎么命名的,我们首先创建3个文件
我们再在Linux下看看C语言是如何处理函数名的
此时我们发现C语言对函数的命名只有函数名本身,和参数无关。
我们在Linux下看看报错信息:我们创建两个f函数,我们在Linux下用gcc编译看报错信息,我们发现这时就会报错说函数命名发生冲突。
因此我们知道C语言对函数的命名只有函数名本身,因此如果在C语言中,函数名相同时,就会报错,因此C语言是不支持函数重载的。
3.总结
1.C++支持函数重载是因为C++在符号表中存储的函数的定义和函数的地址。C++中对函数的命名规则有了新的变化:_Z 函数名长度 函数名 类型首字母 。
因此参数的类型,个数,顺序不同就会不同的命名。名字不同地址不同。这也是为什么C++支持函数重载的原因。
2.我们发现在新的命名规则中是不包括返回值类型的,因此返回值类型不同并不会对函数的命名产生影响,这也是返回值不构成函数重载的原因。
short Add(short left, short right)
{
}
int Add(short left, short right)
{
}
3.C语言中在生成符号表中存储的只是原函数的名字,那么如果函数的名字相同时就会产生命名冲突。这就是为什么C语言不支持函数重载的原因。
(本篇完)
今天的文章[C++] 深入理解C++函数重载底层原理 C++入门(2)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/11165.html