[C/C++]详解C++的函数重载
Posted TT在长大
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C/C++]详解C++的函数重载相关的知识,希望对你有一定的参考价值。
什么是函数重载
在自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
比如:一个经典段子,阿呆给领导送红包时,领导:“你这是什么意思?” 阿呆:“没什么意思,意思意思。” 领导:“那我就不好意思了。” 阿呆:“是我不好意思。” 领导:你肯定有什么意思。 阿呆:真的没有什么意思。 领导:既然没有什么意思,那你是什么意思? 阿呆:其实,我的意思就是想意思意思。
上面这个段子中的 ” 意思 “ 就是一个重载词。
函数重载的概念
函数重载: 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
例如希望交换两个变量的值long,这两个变量有多种类型,可以是 int、float、char、long 等。
#include<iostream>
using namespace std;
int Swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
char Swap(char *a, char *b)
{
char temp = *a;
*a = *b;
*b = temp;
}
long Swap(long *a, long *b)
{
long temp = *a;
*a = *b;
*b = temp;
}
float Swap(float *a, float *b)
{
float temp = *a;
*a = *b;
*b = temp;
}
int main(){
//交换 int 变量的值
int n1 = 1, n2 = 2;
Swap(&n1, &n2);
cout<<n1<<", "<<n2<<endl;
//交换 float 变量的值
float f1 = 1223.335, f2 = 1236.943;
Swap(&f1, &f2);
cout<<f1<<", "<<f2<<endl;
//交换 char 变量的值
char c1 = 'A', c2 = 'D';
Swap(&c1, &c2);
cout<<c1<<", "<<c2<<endl;
return 0;
}
需要注意,当用函数中用到缺省参数而参数类型没有改变就不属于函数重载,如:
int Add(int a, int b)
{
return a + b;
}
int Add(int a, int b = 10)
{
return a + b;
}
此时两个函数的参数类型顺序完全相同
只有返回类型不同也不属于函数重载,如:
int Add(int a, int b)
{
return a + b;
}
short Add(int a, int b)
{
return a + b;
}
名字修饰(Name Mangling)
C++是如何支持函数重载
在C/C++中,程序的运行需要经历 **预处理、编译、汇编、链接。**如下图所示:
-
在日常应用中项目通常是由多个头文件和多个源文件构成,如果当前a.cpp中调用了b.cpp中定义的Add函数时,编译后链接前,a.o的目标文件中没有Add的函数地址,因为Add是在b.cpp中定义的,所以Add的地址在b.o中。
-
所以链接阶段就是专门处理这种问题,链接器看到a.o调用Add,但是没有Add的地址,就会到b.o的符号表中找Add的地址,然后链接到一起。
-
在链接时,面对Add函数连接器会使用哪个名字,每个编译器都有自己的函数名修饰规则。下面我使用了g++演示这个修饰后的名字。
如下图,对应的函数地址经过修饰后都是不相同的
我们可以看到在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中。函数修饰后变成 _Z+函数长度+函数名+类型首字母。
结论:C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。也再次印证了函数重载要求参数不同,而跟返回值没关系。
C语言为什么不支持函数重载
通过与上一节相同的方法在linux下,采用gcc编译完成后,函数名字的修饰没有发生改变。
这里也就解释了C语言没办法支持重载,原因是同名函数没办法区分。
extern “C”
在C++工程中可能需要将某些函数按照C的风格来编译,在函数前加extern “C”,表示该函数按照C语言规则来编译。当C需要调用C++函数时,该C++函数也必须声明为extern “C”。
extern "C" int Add(int a, int b);
此时Add将不能重载。
总结
C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。
以上是关于[C/C++]详解C++的函数重载的主要内容,如果未能解决你的问题,请参考以下文章