11-1 函数重载介绍

考虑以下函数:

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允许创建多个同名函数,只要每个同名函数的形参类型不同(或函数可通过其他方式区分)。在相同作用域内共享名称的函数称为重载函数overloaded function(有时简称为重载overload)。

要重载add()函数,只需声明另一个接受double参数的add()函数:

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

现在同一作用域内存在两个add()版本:

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

double add(double x, double y) // floating point version
{
    return x + y;
}

int main()
{
    return 0;
}

上述程序可编译通过。尽管可能预期这些函数会引发命名冲突,但实际并非如此。由于函数参数类型不同,编译器能够区分这些函数,并将它们视为名称相同但功能独立的函数。

关键要点
只要编译器能区分每个重载函数,函数即可进行重载。若无法区分,则会导致编译错误。

相关内容
运算符也可采用类似方式进行重载。我们将在21.1节——运算符重载介绍 中详细讨论运算符重载。


重载解析介绍

此外,当调用重载函数时,编译器会根据函数调用中的参数尝试匹配相应的重载版本,此过程称为重载解析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); // calls add(int, int)
    std::cout << '\n';
    std::cout << add(1.2, 3.4); // calls add(double, double)

    return 0;
}

该程序编译后输出结果:

image

当调用 add(1, 2) 时提供整数形参,编译器会判定为调用 add(int, int);而调用 add(1.2, 3.4) 时提供浮点形参,编译器则判定为调用 add(double, double)。


实现编译通过

要使使用重载函数的程序能够编译,必须满足两个条件:

  1. 每个重载函数都必须与其他函数区分开来。我们在第11.2节——函数重载区分中讨论了如何区分函数。
  2. 每次对重载函数的调用都必须解析为一个重载函数。我们在第11.3节——函数重载解析与模糊匹配,讨论了编译器如何将函数调用匹配到重载函数。

若重载函数未被区分,或函数调用无法解析为特定重载函数,则会导致编译错误。

下节课我们将探讨如何区分重载函数,随后一节课则将解析编译器如何将函数调用匹配至重载函数。


结论

函数重载通过减少需要记忆的函数名称数量,为降低程序复杂性提供了绝佳途径。它不仅能够,而且应当被广泛运用。

最佳实践
使用函数重载使程序更简洁。

posted @ 2026-03-06 11:15  游翔  阅读(0)  评论(0)    收藏  举报