c++函数重载的原理

来源:互联网 发布:淘宝售后处理时间 编辑:程序博客网 时间:2024/05/17 05:11
一、什么是函数重载:
        函数重载是指在同一作用域内,可以有一组或者多组具有相同函数名,不同参数的函数,这组函数被称为重载函数。
        重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量及复杂度,避免了名字空间的污染,对于程序的可读性有很大的好处。


具体的函数例子:
#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(){       cout<<Add(1, 2)<<endl;       cout<<Add(1.0, 2.0)<<endl;       return 0;}


这里有两个Add函数,如果实在c语言中,就会出现报错:



但是在c++中,它就能编译过去,且没有错误,这就实现了函数的重载。

二、为什么要函数重载:
   由上一个例子可见:
在c语言当中,如果没有函数重载,要实现一个相同功能的函数,要使它能够适应各种类型的数据运算,就要起各种函数的函数名,如:Add_int、 Add_double等待,这样做无形间就加大了命名的复杂性。

三、c++是如何实现函数重载的:
下面我们开始在linux环境下编译这个函数,查看在反汇编下,这些函数的变化:

上图是在反汇编情况下int Add函数的命名。

上图是在反汇编的情况下double Add函数的命名。

由此可见,在c++的环境下,实现函数重载的手段就是在编译的时候,将两个函数名替换成不同的名字,这样就能避免冲突了。
而由上面的两个命名,我们也能简单得发现一点规律:大致就是_Z开头,3返回类型,Add函数名,ii/dd参数。
这点我们可以用另一个函数来试验证:
我们往上添加一个函数:
double Add(int a, double b){        return a+b;}

按照我们的猜想,在反汇编中输出的函数名应该是:_Z3Addid。
验证:

验证结果与我们预期一样。





由上我们就可以来回答一个问题:在C++ 程序中调用被 C 编译器编译后的函数,为什么要加 extern “C”声明?
答:c++语言支持函数重载,C语言不支持函数重载。函数被c++编译后在库中的名字与c语言的不同。假设某个函数的原型为:void foo(int x, int y);
      该函数被c编译器编译后在库中为_foo,而c++编译器则会产生像_foo_int_int之类的名字。
      c++提供了c连接交换指定符号extern “C”来解决名字匹配问题。