目录
1.函数重载的概念
什么是重载呢?在我们学习汉语时往往一个词语,有多重意思,我们需要在不同的情景下去揣摩词语的意思,这就是这个词语被重载了。
函数重载是函数的一种特殊情况,c++允许在同一个域中,声明几个功能类似的同名函数,这几个同名函数,可能是函数的参数列表(参数个数,类型或类型顺序)的不同。常用来处理功能类似但是参数类型不同的问题如下:
参数类型不同:
#include<iostream>
#include<stdio.h>
using std::cout;//将cout和cin展开
using std::cin;
void Add(int *num1, int *num2)
{
int tmp = *num1;
*num1 = *num2;
*num2 = tmp;
}
void Add(double* num1, double* num2)
{
double tmp = *num1;
*num1 = *num2;
*num2 = tmp;
}
int main()
{
int a = 9;
int b = 8;
Add(&a, &b);
return 0;
}
参数的个数不同:
#include<iostream>
#include<stdio.h>
using std::cout;//将cout和cin展开
using std::cin;
void Add(int *num1, int *num2)
{
int tmp = *num1;
*num1 = *num2;
*num2 = tmp;
}
void Add()
{
;
}
int main()
{
int a = 9;
int b = 8;
Add(&a, &b);
return 0;
}
参数的顺序不同:
#include<iostream>
#include<stdio.h>
using std::cout;//将cout和cin展开
using std::cin;
void Print(int a, char c)
{
cout << a << c;
}
void Print(char c, int a)
{
cout << a << c;
}
int main()
{
return 0;
}
2.c++支持函数重载的原理
为什么c++支持函数重载而C语言不支持函数重载呢?我们来一起研究一下!
在c/c++中一个程序要运行起来要经历下面这几个阶段:
在每个阶段阶段中实际上要做编译器和链接器要做很多事情:
如下:
1.实际项目中一个工程会有多个源文件(.c)和多个头文件(.h),每个源文件都会被编译器编译成为一个目标文件,链接前,mian.o的目标文件中是没有 函数sum函数的地址的,因为sum函数是在sum.c中定义的,那么怎么办呢?
2.所以在链接的时候要专门处理这种工作,链接器看到main.o调用了sum函数但是没有Add函数的地址,就会到sum.o的符号表中去找sum的地址,然后链接到一起。(这里如果没有找到函数sum 的地址就会报链接错误)
3.那么在链接时,面对该函数,链接器会按照哪个名字去找sum函数呢?这里每个编译器都有自己的一套函数名修饰规则。
4.在Linux环境下,我们可以看到,gcc的修饰函数后函数的名字不变,g++修饰函数后函数的名字发生了改变,变成:_Z+函数长度+形参类型首字母。
通过C语言编译器(gcc)编译之后的结果:
结论:在linux环境下通过gcc完成编译之后,函数的名字是没有变的。
通过c++编译器编译之后的结果:
结论:在linux环境下通过g++完成编译之后,函数的名字发生了变化:_Z+函数长度+类型首元素,编译器将函数参数的类型的信息添加到修改后的名字中 。
windows下名字修饰规则:
5.我们发现对比windows,Linux环境下的命名规则更加容易理解,在这里不做深入探索,但是它们的道理都是类似的。
6.通过上面的解释我们就知道为什么C语言无法支持函数重载而c++支持函数重载,因为c++是通过函数名修饰规则来区分同名但是参数列表不同的函数的,只有函数的参数列表不同,修饰出来的名字不同就支持重载。
7.如果两个函数的参数列表相同,但是返回值不同是无法构成重载的,因为编译器无法区分。 例如:
int Add()
{
;
}
double Add()
{
;
}
int main()
{
return 0;
}
3.extern "c"的讲解
它有什么作用呢?当一个c程序调用个静态库或者动态库 时,如果这个静态库(动态库)是c++编译的,那么我们就需要给这个静态库(动态库)中我们需要调用的函数前加上extern "c",这样这个静态库(动态库)中的这个函数就会按照C语言的函数名修饰规则来对函数名进行修饰,那么这个C语言程序就可以调用这个静态库(动态库)中的这个函数。
如果加了 extern "c"之后,c++程序再调用静态库(动态库)中的这个函数,就会按照C语言的方式调用。(c++兼容C语言)