函数的重载

我们知道,一个理论提出,必然是为了解决一些问题,为了理解重载,必须先从遇到的问题出发

例如我们想实现这样一个功能

绝对值函数abs,传入一个参数,返回它的绝对值

这看上去很简单,但是,函数声明时,已经声明了函数需要传入参数的类型,如果声明为整型,那么输入浮点型时就会报错,

在C语言中,根据不同的数据类型,有多个绝对值函数fbs,abs,lbs

这无疑加重了记忆负担,那么,是否可以用一个函数实现这个功能呢?

这就引出了函数重载的概念 overloaded

以下是重载函数的一个实例

通过calculateVolume计算不同立体图形的体积

由于不同立体图形的体积计算方式不同,因此需要传入不同的参数,由此需要使用函数的重载

但是注意,它们的返回值是一样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<iostream>
#include<cmath>
using namespace std;
const double Pi = 3.1415926535897932483;
double calculateVolume(double, double, double);
double calculateVolume(double, double);
double calculateVolume(double);
int main()
{
double side, r, h;
cin >> side >> r >> h;
cout << calculateVolume(side, side, side) <<endl;
cout << calculateVolume(r, h) <<endl;
cout << calculateVolume(side);

}
double calculateVolume(double side, double side2, double side3)
{
if (side <= 0)
{
return -1;
}
else {
return side * side * side;
}
}
double calculateVolume(double r, double h)
{
if (r <= 0 || h <= 0)
{
return -1;
}
else {
return Pi * r * r * h;
}
}
double calculateVolume(double side)
{
if (side <= 0)
{
return -1;
}
else
{
return sqrt(3) / 12.0 * side * side * side;
}
}

重载函数的定义规则

  • 函数的形参个数、类型与顺序称为==函数的 “特征标”( signature)==

  • 注意不包括返回值

  • 不同的重载函数定义须具备不同的特征标

  • 对函数调用,编译器根据实参个数、类型与顺序匹配相应的重载函数定义

换而言之,编译器通过形参个数类型和顺序来区分不同的函数

编译器如何实现重载函数?

“静态联编”与名称修饰

​ 通过给不同的重载函数名添加前缀与后缀,对其进行区分

​ 如:max 会被编译器区分为max_1,max_2…

重载解析:

​ 编译器根据实参类型选取并调用最合适的重载函数实例

​ 以上机制都是编译阶段完成的,不占用运行时间。重载函数的运行效率因此和一般函数没有区别