前言
函数的重载是C++不同于C语言的一个地方,他使得我们可以使用相同的函数名定义不同的函数。
提示:以下是本篇文章正文内容,下面案例可供参考
一、注意事项
使用相同的函数名定义不同函数时,每个函数要具有不同的参数列表
int fun(int x)
{...}
int fun(int x,int y)//这两个同名函数包含的元素个数不同,可以这样定义
{...}
int fun(int x)
{...}
int fun(double x)//这两个同名函数包含的元素类型不同,可以这样定义
{...}
int fun(int x)
{...}
int fun(int y)//这两个同名函数包含的元素个数和类型相同,不可以这样定义。因为int x和int y所代表的形参本质上一样
{...}
int fun(int x)
{...}
double fun(int x)//这两个同名函数包含的元素个数和类型相同,不可以这样定义,虽然返回类型不同,但是参数列表相同,这样也不行
{...}
同理还有
int fun(int x)
{...}
double fun(const int x)//g++认为const int 和int是一个平凡转换,是同级别的东西,所以也会重定义
{...}
二、底层原理
这里涉及到一个mangling问题
mangling的目的就是为了给重载的函数不同的签名,以避免调用时的二义性调用。
举个栗子
void func(char)
void func(int)
void func(int, int)
void func()
编译后对应的编码
0000000000000040 T __Z4funcc
0000000000000020 T __Z4funci
0000000000000030 T __Z4funcii
0000000000000010 T __Z4funcv
不同的func()对应不同的码,方便计算机区分
三、名称查找
由于函数重载的关系,一个翻译单元内可能会有多个同名函数,那么调用的时候怎么知道要调用哪一个呢?
调用时有以下规则
1.限定查找
比如我指定在某个名字空间内查找
namespace::fun()
2.非限定查找
如果没有指定名字空间,那就优先现在当前域内查找,逐级向外查找。注意查找时要从下向上找。因为程序是从上向下进行处理的
void fun(int)//第一个fun
{std::cout<<1;}
namespace MYNS
{
void g()
{
fun(3);
}
void fun(double)//第二个fun
{std::cout<<2;}
}
int main()
{
MYNS::g();
}
比如我们看上面这个程序,主函数里调用g()时,会打印出1,因为虽然第二个fun()在当前域内,但因为程序是从上向下进行处理的,调用g()时他不知道MYNS里有fun函数。除非你在void g()前面加一句void fun(double);作为声明。