章节目录

被重载函数之间互相区分

本节阅读量:

在上一课中介绍了函数重载的概念,它允许我们创建具有相同名称的多个函数,只要每个同名函数具有不同的参数类型(或者可以以其他方式区分函数)。

在本课中,我们将更仔细地看一看重载函数是如何区分的。未正确区分的重载函数将导致编译器报错。


如何区分重载函数

函数属性 是否用于区分
参数个数
参数类型 排除参数的类型别名,const限定符。但包含省略号
返回类型

请注意,函数的返回类型不用于区分重载函数。我们稍后将对此进行更多讨论。


基于参数个数的重载

只要每个重载函数具有不同数量的参数,就可以区分重载函数。例如:

1
2
3
4
5
6
7
8
9
int add(int x, int y)
{
    return x + y;
}

int add(int x, int y, int z)
{
    return x + y + z;
}

编译器可以很容易地区分,具有两个整数参数的函数调用应该是add(int, int),而具有三个整数参数的函数调用应是add(int, int, int)。


基于参数类型的重载

只要每个重载函数的参数类型列表是不同的,就可以区分函数。例如,以下所有重载都是不同的:

1
2
3
4
int add(int x, int y); // 整数版本
double add(double x, double y); // 浮点数版本
double add(int x, double y); // 整数与浮点数混合版本
double add(double x, int y); // 整数与浮点数混合版本

由于类型别名(或typedef)不是不同的类型,因此使用类型别名的重载函数与使用原始类型的函数没有区别。例如,以下所有函数都无法区分(并将导致编译错误):

1
2
3
4
5
6
typedef int Height; // typedef
using Age = int; // 类型别名

void print(int value);
void print(Age value); // 无法与 print(int) 区分
void print(Height value); // 无法与 print(int) 区分

对于通过值传递的参数,也不考虑const 限定符。因此,以下函数不被认为是有区别的:

1
2
void print(int);
void print(const int); // 无法与 print(int) 区分

函数的返回类型不用于区分

在区分重载函数时,不考虑函数的返回类型。

考虑这样的情况,您希望编写一个返回随机数的函数,但需要一个返回int的版本,以及另一个返回double的版本。您可能会尝试这样做:

1
2
int getRandomValue();
double getRandomValue();

在Visual Studio 2019上,这会导致以下编译器错误:

1
error C2556: 'double getRandomValue(void)': overloaded function differs only by return type from 'int getRandomValue(void)'

这是有意义的。如果您是编译器,并且看到了以下语句:

1
getRandomValue();

您将调用两个重载函数中的哪一个?这无法区分清楚。

解决此问题的最佳方法是为函数指定不同的名称:

1
2
int getRandomInt();
double getRandomDouble();

类型签名

函数的类型签名(type signature)被定义为函数头中用于区分函数的部分。在C++中,这包括函数名、参数数量、参数类型和函数级限定符。它显然不包括返回类型。


名称修饰(Name mangling)


11.0 函数重载简介

上一节

11.2 函数重载决议

下一节