C++ 允许在同一作用域中的某个函数和运算符指定多个定义,分别称为函数重载和运算符重载。
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数或重载运算符时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。选择最合适的重载函数或重载运算符的过程,称为重载决策。
1. 函数重载
在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同,不可以使用返回值区分不同的函数。您不能仅通过返回类型的不同来重载函数。
下面的实例中,同名函数 print() 被用于输出不同的数据类型:
#include <iostream>
using namespace std;
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
int main(void)
{
printData pd;
// 输出整数
pd.print(5);
// 输出浮点数
pd.print(500.263);
// 输出字符串
char c[] = "Hello C++";
pd.print(c);
return 0;
}
编译器调用重载函数的准则:
将所有同名函数作为候选者
尝试寻找可行的候选函数
1、精确匹配实参
2、通过默认参数能够匹配实参
3、通过默认类型转换匹配实参
匹配失败
1、最终寻找到的候选函数不唯一,则出现二义性,编译失败
2、无法匹配所有候选者,函数未定义,编译失败
可见,两个函数的入口地址不同,因此,它们是不同的函数。这两个标识符是不一样的,C++编译器就是通过这种方式区别重载函数的。
2. 函数重载与指针
#include <stdio.h>
#include <string.h>
int func(int x)
{
return x;
}
int func(int a, int b)
{
return a + b;
}
int func(const char* s)
{
return strlen(s);
}
typedef int(*PFUNC)(int a);
int main(int argc, char *argv[])
{
int c = 0;
PFUNC p = func;
c = p(1);
printf("c = %d\n", c);
return 0;
}
在给p赋值的时候,我们使用了func,但是这里并没有指明参数,编译器是怎么知道这个func函数指的是第一个func函数呢?
函数重载遇上指针:
将重载函数名赋值给函数指针时
1、根据重载规则挑选与函数指针参数列表一致的候选者
2、严格匹配候选者的函数类型与函数指针的函数类型