函数重载简介

考虑以下函数:

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

这个简单函数将两个整数相加并返回整数结果。然而,如果我们还想提供一个能够相加两个浮点数的函数,上述 add() 就不再适用——浮点实参会被转换成整数,从而丢失小数部分。

一种解决方法是给不同版本的函数起不同名字:

int addInteger(int x, int y)
{
    return x + y;
}

double addDouble(double x, double y)
{
    return x + y;
}

但这样做需要:

  • 维护一套一致的命名规则;
  • 记住每个函数名;
  • 在调用时选准正确的名字。

一旦需求扩展到“三个整数相加”,名字管理很快就会变得繁琐。

函数重载简介

C++ 提供了优雅的解决方案——函数重载 (function overloading):只要同名函数的参数类型不同(或可通过其他方式区分),即可在同一作用域内定义多个同名函数。这些同名函数称为重载函数(简称 overload)。

重载 add() 的示例:

double add(double x, double y)
{
    return x + y;
}

现在作用域内有两个 add()

int add(int x, int y)      // 整数版本
{
    return x + y;
}

double add(double x, double y) // 浮点版本
{
    return x + y;
}

int main()
{
    return 0;
}

程序可正常编译。虽然看起来同名,但因参数类型不同,编译器能够区分它们,视为两个仅名字相同的独立函数。

关键洞察 只要重载函数能被编译器区分,就合法;否则产生编译错误。

相关内容 运算符亦可重载,见运算符重载简介。

重载决议简介

当调用重载函数时,编译器会根据实参匹配最合适的版本,这一过程称为重载决议 (overload resolution)。示例:

#include <iostream>

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

double add(double x, double y)
{
    return x + y;
}

int main()
{
    std::cout << add(1, 2);       // 调用 add(int, int)
    std::cout << '\n';
    std::cout << add(1.2, 3.4);   // 调用 add(double, double)
    return 0;
}

输出:

3
4.6
  • 调用 add(1, 2) 时,实参为整数,匹配 add(int, int)
  • 调用 add(1.2, 3.4) 时,实参为浮点数,匹配 add(double, double)

编译条件

使用重载函数的程序必须满足:

  1. 各重载函数必须可区分(见函数重载区分)。
  2. 每次调用必须能唯一匹配一个重载版本(见重载决议与二义性)。 否则编译报错。

下一课将探讨如何区分重载函数,再下一课研究编译器如何决议调用。

结论

函数重载通过减少需要记忆的函数名数量,显著降低程序复杂度,应当积极使用。

最佳实践

利用函数重载简化程序设计。

关注公众号,回复"cpp-tutorial"

可领取价值199元的C++学习资料

公众号二维码

扫描上方二维码或搜索"cpp-tutorial"