代码仓库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++可以进行函数重载,详见下一篇文章:名字粉碎(名字修饰)