C++之函数重载
重载的引入使得C++的灵活性有了极大提升,重载体现在只要在定义函数时形参列表(形参个数、类型、顺序你)不同,就可以重复定义同名函数。值得注意的是,函数的重载这里并对函数的返回值做出要求,那么也就意味着c++中函数的重载不关心返回值,即若定义了两个函数名、形参列表相同,返回值不同,那么编译器也会认为这两个函数其实是一个函数,在编译期间就会报错。
事实上,C++编译器在编译时还是关心函数的返回值的。
以VS2013为例:
#include<iostream>
using namespace std;
int Add(int a,int b)
{
return a+b;
}
float Add(float a,float b)
{
return a+b;
}
int main()
{
Add(10,20);
Add(20.0f,30.0f);
return 0;
}
程序从编译到运行出结果几个阶段。其中一个阶段提到生成符号表。
我们来看一下上边的函数成的符号表。符号表是在.map文件里,在vs里默认不显示符号表文件。要想显示出来,这样设置:
工程名右击—>属性—->配置属性—->链接器—–>调试—->生成映射文件—>选择是;
这里我们可以看出,在.cpp文件中,虽然两个函数的函数名一样,但是他们在符号表中生成的名称不一样。
‘?’表示名称开始,‘?’后边是函数名“@@YA”表示参数表开始,后边的3个字符分别表示返回值类型,两个参数类型。“@Z”表示名称结束。
现在问题来了,既然C++中对函数返回值类型有符号标记,那为什么不将函数返回类型考虑到函数重载中呢?
——这是为了保持解析操作符或函数调用时,独立于上下文(不依赖于上下文)
float sqrt(float);
double sqrt(double);
void f(double da, float fla)
{
float fl=sqrt(da);//调用sqrt(double)
double d=sqrt(da);//调用sqrt(double)
fl=sqrt(fla); //调用sqrt(float)
d=sqrt(fla); //调用sqrt(float)
}
如果返回类型考虑到函数重载中,这样将不可能再独立于上下文决定调用哪个函数。