代码仓库shanchuann/CPP-Learninng

函数重载

在 C 语言中,编译时会对函数名添加前缀,如func会变为_func,这也是为什么 C 语言不支持重载的原因,所以 C 语言通过函数名直接来对函数进行区分

1
2
void func_i(int a) {}
void func_d(double a) {}

C++提供函数重载的概念:在 C++中可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同或参数类型相同但参数个数不同,称为函数重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void func(int a) {
cout << "func with int: " << a << endl;
}
void func(int a, int b) {
cout << "func with two int: " << a << ", " << b << endl;
}
void func(double a) {
cout << "func with double: " << a << endl;
}
int main() {
func(10);
func(10, 20);
func(10.5);
return 0;
}
1
2
3
func with int: 10
func with two int: 10, 20
func with double: 10.5
  • 如果两个函数的参数的顺序不同,也认为属于函数的重载
1
2
3
4
5
6
void print(int a, double b) {
cout << "int, double: " << a << ", " << b << endl;
}
void print(double a, int b) {
cout << "double, int: " << a << ", " << b << endl;
}
  • 当仅有返回类型不同因为具有二义性,因从被认为是重定义,不作为函数重载

  • 参数表的比较过程与参数名无关

  • 若两个函数仅为缺省实参不同,则第二个声明被认为是第一个的重复声明

1
2
void func(int a,int b = 10){}
void func(int a){}
  • typedf 名为现有的数据类型提供了一个替换名,并没有创建一个新类型,因此如果两个函数参数表的区别只在一个用了 typedef,另一个为 typedef 相应的类型,则被视为相同的参数列表

  • 当形参类型有 const 或 volatile 修饰,若形参按值传递方式定义,则在识别函数声明是否相同时不考虑 const 或 volatile 修饰符,若以指针或引用定义时则需要考虑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//按值传递方式定义
void print(int a) {
cout << "int: " << a << endl;
}
void print(const int a) {
cout << "const int: " << a << endl;
}
//以指针或引用定义
void print(int& a) {
cout << "int: " << a << endl;
}
void print(const int& a) {
cout << "const int*: " << a << endl;
}
int main() {
int x = 10;
const int y = 20;
print(x); //调用第一个print
print(y); //调用第二个print
print(12); //调用第二个print
return 0;
}

print(12);中 12 为字面量,const int& a 为”万能引用”,既可以引用左值,又能引用右值,可以引用常量,变量,字面量

函数重载解析步骤如下:

  1. 确定函数调用考虑的函数重载的集合,确定函数调用实参表的属性
  2. 从重载函数集合中选择函数,该函数可以在(给出实参个数和类型)的情况下可以调用函数
  3. 选择与调用最匹配的函数

为什么 C++可以进行函数重载,详见下一篇文章:名字粉碎(名字修饰)