C++超详细讲解函数重载
作者:tianyvHon
C++ 允许多个函数拥有相同的名字,只要它们的参数列表不同就可以,这就是函数的重载(Function Overloading),借助重载,一个函数名可以有多种用途
1 函数重载的定义
函数重载:使用同一个函数名定义不同的函数。从本质上来看,就是互相独立的不同函数,每一个函数类型不同。因此,函数重载是由函数名和参数列表决定的。
注意:函数返回值不能作为函数重载的重要依据!
2 构成函数重载的条件
当满足以下三个条件之一时,便可以构成函数重载
函数参数个数不同
// 函数类型:void(int) void Demo(int x) { printf("x = %d\r\n", x); } // 函数类型:void(int, int) void Demo(int x, int y) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); } // 函数类型:void(int, int, int) void Demo(int x, int y, int z) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); }
函数参数类型不同
void Demo(int x) { printf("x = %d\r\n", x); } void Demo(char x) { printf("x = %c\r\n", x); }
函数参数顺序不同
void Demo(char c, int x) { printf("x = %d\r\n", x); printf("c = %c\r\n", c); } void Demo(int x, char c) { printf("x = %d\r\n", x); printf("c = %c\r\n", c); }
但是,如果函数的参数类型均相同,仅仅顺序不同同样会出错,如下所示的代码:
void Demo(int x, int y, int z) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); } void Demo(int y, int x, int z) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); }
3 编译器调用重载函数的准则
编译器编译代码的流程:
将所有同名函数作为候选者
尝试寻找可行的候选函数
- 精确匹配实参
- 通过默认参数匹配实参
- 通过默认类型转换匹配实参
匹配成功
如果编译失败的话,有如下两种情况:
- 找到的候选函数不唯一,出现二义性,失败
- 无法匹配所有候选者,函数未定义,失败
4 函数重载的注意事项
4.1 避开重载带有指定默认值参数的函数
在我们使用函数重载的过程,要注意避开重载带有指定默认值参数的函数。否则在使用的过程中,会出现二义性,导致编译失败。如下代码所示的错误示例:
void Demo(int x, int y) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); } void Demo(int x, int y, int z = 0) { printf("x = %d\r\n", x); printf("y = %d\r\n", y); printf("z = %d\r\n", z); } int main() { Demo(1, 2); return 0; }
当对重载函数进行调用时 Demo(1, 2)
,编译器是无法分辨我们到底是使用 void Demo(int x, int y)
函数,还是使用 void Demo(int x, int y, int z = 0)
函数,因此无法编译通过。
4.2 注意函数重载遇上函数指针
重载函数的名称赋值给函数指针后,当对函数指针进行调用时,将根据下面的方式进行函数匹配
- 首先,根据重载规则挑选与函数指针参数列表一致的候选者
- 然后,根据候选者的函数类型与函数指针的函数类型进行匹配
通过如下代码所示的示例进行解释:
typedef int(*PDemo)(int i); // Demo1 int Demo(int x) { return x; } // Demo2 int Demo(int x, int y) { return x * y; } // Demo3 int Demo(const char* c) { return strlen(c); } int main() { int i = 0; PDemo pd = Demo; // 一个参数,因此不是Demo1就是Demo3 // pd的函数类型是int(int)与Demo1相同,因此就是Demo1 i = pd(1); return 0; }
如果将上述示例中函数指针的返回类型由 int
更改成 double
,仍通过 pd(1)
进行调用的话,该程序将不能被编译过,因为没有与之匹配的重载函数。
- 参数列表没有问题
- 函数返回值类型有问题,因为函数类型包含函数的返回值类型
4.3 C++编译器不能以 C 的方式编译重载函数
由于 C++ 编译器将函数名和参数列表编译成目标名,C 编译器将函数名编译成目标名,这样 C 编译器编译后的重载函数的目标名一致,于是便无法实现重载函数的功能。
到此这篇关于C++超详细讲解函数重载的文章就介绍到这了,更多相关C++函数重载内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!