前言
自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
函数重载
- 一、函数重载定义
- 二、函数重载的条件
- 1. 参数类型不同
- 2. 参数个数不同
- 3. 参数类型顺序不同
- 三、函数重载的原理--名字修饰(name Mangling)
- 四、补充与总结
一、函数重载定义
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似,数据类型不同的问题。
例如:
#include<iostream>
using namespace std;
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
int main()
{
int a = Add(1, 2);
double b = Add(1.1, 2.2);
cout << a << endl;
cout << b << endl;
return 0;
}
我们可以看到定义了一个Add函数来求两个不同类型数的和,在调用过程中系统会自动根据其实参的类型不同来实现准确调用。
在C++中不仅函数可以重载,运算符也可以重载。例如:
运算符<<,>>。既可以做移位运算符,也可以做输出,输入运算符。
二、函数重载的条件
1. 参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
2. 参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
3. 参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
注意:函数重载的返回类型可以相同也可以不相同,仅仅返回类型不同不足以成为函数的重载。因为调用函数不一定就需要去接收返回值
三、函数重载的原理–名字修饰(name Mangling)
为什么C++支持函数重载,而C语言不支持函数重载呢?
在C/C++中,一个程序要运行起来,需要经历以下几个阶段:预处理、编译、汇编、链接。
在编译阶段,编译器会对函数名进行修饰
- C语言中
由于C语言只会给函数进行简单的重命名,具体的方法是给函数名之前加上”_”;所以加入两个函数名相同的函数在编译之后的函数名也照样相同,调用时会因为不知道到底调用那个而出错,所以C语言中不支持函数重载。 - C++中
在编译阶段,虽然两个函数的函数名一样,但是编译器会根据形成函数重载的条件对它们的函数名进行修饰,让他们在符号表中生成的名称不一样。
由于在.cpp文件中,两个函数生成的符号表中的名称不一样,所以是可以编译通过的。
C++在不同的平台下修饰规则不太一样,Windows下vs的修饰规则有些复杂,而Linux下g++的修饰规则简单易懂
-
在windows 下
?Add@@YAHHH@Z
?代表开始
Add代表原本的函数名
@@YA代表参数的开始
第一个H代表返回值类型int
后面的H代表int参数,M代表float参数
@Z表示名称结束。 -
在Linux下
_Z3Addii
_Z代表开始
3代表原本函数名的长度
Add代表原本的函数名
第一个i代表第一个参数是int
第二个i代表第二个参数是int
可以看出在Linux下g++的函数修饰后变成【_Z+函数长度+函数名+类型首字母】。
四、补充与总结
多态:用同一个东西表示不同的形态;多态分为:
- 静态多态(编译时的多态);
- 动态多态(运行时的多态);
函数重载就是一种静态多态;
重载函数通常用来在同一个作用域内 用同一个函数名 命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。