c++函数重载的实现原理

来源:互联网 发布:剑灵火炮兰捏脸数据图 编辑:程序博客网 时间:2024/06/14 08:48

1.c++问什么引入函数重载
在c语言中,如果我们写两个函数名相同的函数,编译器会告诉我们,函数重定义的错误。我们还会遇到下面这个问题:如果我们写一个计算int类型的加法,另一个计算double类型的加法,我们必须起两个不同的函数名。而在c++中我们可以解决这两个问题。我们可以用相同的函数名,只有参数列表不同可以。
2.函数重载的条件
(1)要求重载的函数必须在同一个作用域
(2)函数的参数列表不同(参数个数不同和参数类型不同)
(3)返回值可同可不同。
3.下面我们用一个列子来深入探究函数重载的原理
下面代码为测试代码

#include<iostream>using namespace std;int Add(int a,int b){    return a+b;}double Add(double a,double b){    return a+b;}int main(){    int a=1,b=2;    double c=1.2,d=2.4;    Add(a,b);    Add(c,d);    return 0;}

结果分析
(1)linux平台
我们通过指令:objdump test -t 可以得到源文件的汇编文件
这里写图片描述
在汇编文件中我们可以找到下面的内容
这里写图片描述
我试验了好的函数,大致可以得出如下结论:c++代码文件会把相同函数解析成不同的汇编函数名,大概的解析方法是 _Z[函数名长度][函数名][参数列表的类型首字母]。这样的话,编译器在调用同名函数时,就不会产生二义性,这样就达到了函数重载的要求。
(2)在window平台下使用vs2013
要得到源文件编译后的文件,我们需要在vs设置下,方法如下:工具栏“项目”—>属性—->配置属性—->链接器—->调试—->映射文件(设置为是);
然后我们在创建项目文件夹的Debug里面找.Map文件。我们就可以找到下面的内容
这里写图片描述
我们可以看到它的函数编译后的命名和linux下的不同,大致格式为 ?[函数名]@@YAHHH@z (只用函数名和YA后面的格式和@z是固定的,剩下的都是固不定的,它的命名代了返回值的参数类型。(H—int,N—double,X—void)
经过我的讲解,我想函数重载的原理大概就清楚了把,总结下来就是:源文件通过编译后,将相同函数名,按照一定的格式,改变成可以区分的,去除了函数在代用时的二义性,从而实现函数的重载。
4.下面我们看下函数重载的一个面试题
在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?
下c编译下的函数名是下面的名称
这里写图片描述
而在c++编译下为
这里写图片描述
如果不加 extern “C”声明,c++不能找到相应的函数名,所以就出错
如果加了extern “C”声明,就会告诉编译器,我是c文件,查找时,请按c文件解析后的名字来找我,所以就不会出错。
总结:C++语言支持函数重载, C 语言不支持函数重载。函数被 C++编译后在库中的名字
。 C 语言的不同。假设某个函数的原型为: int Add(int a,int b);该 函 数 被 C 编 译 器 编 译 后 在 库 中 的 名 字 为 _foo, 而 C++编 译 器 则 会 产 生 像_Add之类的名字。
C++提供了 C 连接交换指定符号 extern“C”来解决名字匹配问题。

原创粉丝点击