C++练级之初级:第三篇

C++练级之初级:第三篇

1.探索C++中函数重载的本质

首先我们先解决一下为什么C++支持函数重载,而C语言不支持?

这里就不得不提起编译链接了;
这是编译链接篇
C++练级之初级:第三篇_第1张图片
以这三个简单的文件为例:

在这里插入图片描述

  1. 预处理阶段: 头文件的展开,条件编译,宏的替换,注释的删除等,最终处理完这些后test.c就会变成test.i,add.c就会变成add.i;
    C++练级之初级:第三篇_第2张图片

  2. 编译阶段: 词义分析,符号汇总(函数名,全局变量),语法分析,语义分析,将代码转换为汇编代码,最终处理完这些后test.i会变成test.s,add.i会变成add.s,注意这里只是对符号进行了汇总还没有获取到符号的地址;

C++练级之初级:第三篇_第3张图片
3. 汇编阶段: 形成符号表,将汇编语言转换为二进制的机器语言,然后test.s变成test.o,add.s变成add.o;

C++练级之初级:第三篇_第4张图片
4. 链接阶段: 进行符号表的合并和重定位,段表的合并,相当于把多个.c文件链接起来了,最后在windows环境下生成.exe文件,在Linux环境下生成a.out(可以改),这里就能获得最终的函数地址

C++练级之初级:第三篇_第5张图片


我们以Linux环境为例
C++练级之初级:第三篇_第6张图片

这是Linux下gcc (C语言编译器) 编译后的结果:

C++练级之初级:第三篇_第7张图片

我们发现C语言在编译期间函数名并未发生改变;

这是Linux下g++ (C++编译器) 编译后的结果:

C++练级之初级:第三篇_第8张图片

我么发现C++在编译阶段函数名进行了修饰;


C++的函数名字修饰规则是什么?

【_Z+函数名长度+函数名+数据类型首字母】;

综上所述: C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。

为什么当函数参数列表项同时,返回值类型不同不构成函数重载?

假设函数名字修饰规则中有返回值的写入,那么在链接阶段编译器是无法区分你要调用的是哪个函数;


在windows环境下,vs也有自己的函数名字修饰规则,逻辑上是和Linux下函数名字修饰规则一样的,但是vs中的函数名字的修饰规则太复杂;

C++练级之初级:第三篇_第9张图片

你可能感兴趣的:(c++,开发语言)