1.什么是函数重载
重载函数(overload function)是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,也就是说用同一个函数完成不同的功能。这就是重载函数。重载函数常用来实现功能类似而所处理的数据类型不同的问题。不能只有函数返回值类型不同。(函数重载与函数的返回值无关)
#include <iostream>
using namespace std;
int Add(int left, int right)
{
return left+right;
}
double Add(double left, double right)
{
return left+right;
}
long Add(long left, long right)
{
return left+right;
}
int main()
{
cout<<Add(1, 2)<<endl;
cout<< Add(3.0, 4.0)<<endl;
cout<< Add(5L, 6L)<<endl;
return 0;
}
由这个代码可以看出,函数调用可以通过不同的参数匹配不同的函数。
2.为什么要使用函数重载
- 试想如果没有函数重载机制,如在C中,你必须要这样去做:为这个print函数取不同的名字,如print_int、print_string。这里还只是两个的情况,如果是很多个的话,就需要为实现同一个功能的函数取很多个名字,如加入打印long型、char*、各种类型的数组等等。这样做很不友好!
- 类的构造函数跟类名相同,也就是说:构造函数都同名。如果没有函数重载机制,要想实例化不同的对象,那是相当的麻烦!
- 操作符重载,本质上就是函数重载,它大大丰富了已有操作符的含义,方便使用,如+可用于连接字符串等!
3.编译器是如何解析函数调用
编译器实现函数调用解析机制的时候,首先找出一些同名的候选函数,然后从函数中找出最符合的,如果找不到就报错。下面介绍函数解析的方法:编译器在对重载函数调用进行处理时由语法分析,C++文法,符号表,抽象语法树交互处理,交互图如下
- 由匹配文法中的函数调用获取函数名
- 获得函数各参数表达式形式类型
- 语法分析器查找重载函数,符号表内部经过冲在解析返回最佳的函数
- 语法分析器创建抽象语法树,将符号表中存储的最佳函数绑定到抽象语法树上
函数重载解析大致分为三步
- 根据函数名确定候选集
- 从候选函数集中选择可用函数集合
- 从可用函数集合中确定最佳函数,或由于模棱两可返回错误
4.为什么C没有函数重载而C++有
下面是Linux环境下C代码与C++代码的反汇编
在C/C++中,一个程序运行起来,需要经过以下阶段,预处理,编译,汇编,链接。
采用gcc会发生命名的冲突,所以C不能重载
采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。重载函数的名字发生了改变,这样就不会存在命名冲突问题。返回类型+函数名+参数列表