为什么C++支持重载而C语言不支持重载

一个函数在C++中能够被重载,但是在C语言确不能被重载的,是由于函数名在内存中存储方式不同所导致的。


C语言

例如在C语言中,有以下三个函数,只给声明不给定义!

int fun(int a, int b);
int fun2(int a, char b);
char fun3(char a, char b);

在main函数中调用之

int main()
{
    fun(1, 2);
    fun2(2, 3);
    fun3(3, 4);
    system("pause");
    return 0;
}

会发现4个连接错误:
这里写图片描述

我们仔细来看一下,在C语言中,编译器区分一个函数,仅仅是靠 “_” + 函数名来区分的,如果我们将三个函数写成同名函数呢:

int fun(int a, int b);
int fun(int a, char b);
char fun(char a, char b);

int main()
{
    fun(1, 2);
    fun(2, 3);
    fun(3, 4);
    system("pause");
    return 0;
}

会发现,编译通不过,报出重定义错误
这里写图片描述
这是当然的,因为三个函数的函数名相同,在编译器看来都是_fun,当出现第二个时,编译发现这个函数名已存在,便出现重定义编译失败。
这也就是为什么C语言不支持重载的原因,只因为不论什么,函数名只要相同编译器就人为是同一个标识符,便不加以区分。


C++

那么C++为什么支持重载呢?我们接着来看:

int fun(int a, int b);
int fun2(int a, char b);
char fun3(char a, char b);

int main()
{
    fun(1, 2);
    fun2(1, 'c');
    fun3('1', '2');
    system("pause");
    return 0;
}

同样的函数,同样不进行定义直接调用,会发现:
这里写图片描述
同样是4个连接错误,但是不同的是,函数名变长了,我们仔细研究发现一个函数在C++中的符号总是以?函数名@@YA开头,之后是H或者D,最后是以@Z结尾,共三部分。我们在仔细看会发现,在第二部分中H表示intD表示char,且第一个表示返回值,之后的表示函数的参数。

int fun(char a, char b, int c);就是 ?fun@@YAHDDH@Z

这样编译器就能区分每个函数了,尽管函数名相同,但只要是参数不同,在编译器看来也是不同的标识符:

int fun(int a, int b);
int fun(int a, char b);
char fun(char a, char b);

int main()
{
    fun(1, 2);
    fun(1, 'c');
    fun('1', '2');
    system("pause");
    return 0;
}

当三个函数构成重载时,会发现:
这里写图片描述

函数名相同,但编译器还是能够区分的。


总结:

虽然在两个语言中, 函数的调用约定都是_cdecl,但是由于函数在内存中的存储方式不相同,C语言是“_” + 函数名形式,而C++是?函数名@@YA返回值 参数@Z形式,导致C++支持重载,而C语言不支持重载。

猜你喜欢

转载自blog.csdn.net/xiaozuo666/article/details/81258459
今日推荐