【C++】为什么C++会支持函数重载

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

函数重载

1.概念

2.支持函数重载的原理 

2.1准备知识

2.2原理


函数重载

1.概念

        在C语言中是不允许同名函数存在的。但是在一个作用域种比如加法函数想要实现各种类型的数据相加要定义多个函数但是这些函数实现的功能类似却不可以同名就非常麻烦。所以C++里面引入了函数重载这一概念允许同名函数的存在。

        函数重载是函数的一种特殊情况C++允许在同一作用域中声明几个功能类似的同名函数这些同名函数的形参列表(参数个数类型 类型顺序)不同常用来处理实现功能类似数据类型
不同的问题。如下就是函数重载两个Add 函数的参数类型不同

        也可以是参数个数不同如下

        或者是参数的类型顺序不同注意是参数类型的顺序如下

         但是一定不可以是参数类型相同但是变量名顺序不同如下就是错误的。参数的名字变了并没有本质上的改变该是什么类型的还是什么类型一定要是类型顺序不同。

2.支持函数重载的原理 

2.1准备知识

        首先我们要了解一个.c 文件生成 .exe 文件的过程中发生了什么。具体可以见这篇文章【C语言】你知道.c文件是如何变成.exe文件的吗_Austerlitzl的博客-CSDN博客_

         下图是编译链接过程的一个概括图。 

 

        下图是编译环境四个阶段。

1. 实际项目通常是由多个头文件和多个源文件构成而通过对编译链接的了解我们可以知道【当前 main.c 中调用了 sum.c 中定义的 sum 函数时】编译后链接前main.o 的目标文件中没有 sum 的函数地址因为 sum函数 是在 sum.c 中定义的所以 sum 的地址在 sum.o 中。那么怎么办呢
2. 所以链接阶段就是专门处理这种问题链接器看到 main.o 调用 sum 但是没有 sum 的地址就会到 sum.o 的符号表中找 sum 的地址然后链接到一起。
3. 那么链接时面对 sum 函数链接器会使用哪个名字去找呢这里每个编译器都有自己的函数名修饰规则
4. Windows下vs的修饰规则过于复杂Linux下g++的修饰规则简单易懂所以下面使用g++演示了这个修饰后的名字。

2.2原理

        C++支持函数重载的原理就是——名字修饰。简单地说一个C语言程序如果对他进行编译那么链接器在寻找一个函数的时候是原原本本去寻找它的名字如果写了相同名字的函数编译器寻找的时候无法区分。但是对于C++程序而言会根据参数个数参数类型对它的函数名进行一定程度上的修饰这样即使是同名函数由于参数个数或者参数类型或者参数类型顺序不同修饰之后的函数名也是不同的链接器就可以区分

        由于在不同环境下修饰规则有所不同。而Linux环境下函数名修饰规则比较简单所以用Linux做演示如下是C语言的函数调用明显发现没有任何修饰。

        但是如下是C++ 的程序可以明显看出其函数名是被修饰的。其修饰规则也不难 _Z 是固定的然后加上的数字是函数名长度接着加上函数名最后加上参数类型的首字母

        如果规定 C++ 的返回值也参与名字修饰呢那么遇到同名函数的参数完全一致但是返回值不同是否也可以区分
        首先要清楚如果其返回值也参与名字修饰那么修饰之后的名字肯定也是不一样的链接器肯定可以区分不同名字的函数。
        但是我们调用函数的时候不一定每次都需要它的返回值如下图main() 函数里面调用两个Add 函数但是谁知道它是调用返回值是 double 的还是返回值是 int 的所以不可取。

         也可以看一下 VS 环境之下只声明一个函数却不定义自然是找不到的查看报错情况。如下是一个 C语言程序红色箭头其报错信息最下面红色方框可以看出C语言确实没有名字修饰。 

         但是C++ 程序就不一样了如下图通过红色方框的内容确实可以看出有名字修饰但是其规则比较复杂。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: c++