第四节 · 分身术 · 函数重载
在日常生活中,"打开"这个词可以用在很多场景:打开门、打开书、打开电脑、打开网页……虽然都叫"打开",但具体的操作却完全不同。
C++ 中也有类似的机制,允许我们用同一个名字定义多个函数,只要它们的参数不同。这就是函数重载(Function Overloading)。
假设我们要编写一个函数来计算两个数的最大值。对于整数和浮点数,我们需要分别处理:
不使用重载的写法:
int maxInt(int a, int b)
{
return (a > b) ? a : b;
}
double maxDouble(double a, double b)
{
return (a > b) ? a : b;
}使用函数重载:
int max(int a, int b)
{
return (a > b) ? a : b;
}
double max(double a, double b)
{
return (a > b) ? a : b;
}现在,我们可以用同一个函数名 max 来处理不同类型的参数:
编译器会根据传入参数的类型,自动选择调用哪个版本的函数。这个过程称为重载决议(Overload Resolution)。
重载的规则
函数重载的依据是函数签名的不同。函数签名包括函数名和参数列表(参数的类型、个数和顺序),但不包括返回类型。
以下情况可以构成重载:
以下情况不能构成重载:
重载与默认参数
当函数重载与默认参数结合使用时,需要注意避免二义性:
当调用 func(5) 时,它既可以匹配 func(int a),也可以匹配 func(int a, int b = 10)(使用默认参数)。编译器无法判断应该调用哪一个,因此会报错。
重载决议的过程
当编译器遇到函数调用时,它会按照以下步骤选择最佳匹配:
精确匹配:参数类型完全相同。
类型提升:如
char到int,float到double。标准转换:如
int到double,指针到void*。用户定义的转换:使用转换函数或转换构造函数。
如果编译器找不到唯一的最佳匹配,就会报错,提示调用有二义性。
const 重载
对于引用和指针参数,const 和非 const 版本可以构成重载:
这种技术常用于实现容器的元素访问:对于非 const 对象返回可修改的引用,对于 const 对象返回只读引用。
成员函数的重载
类的成员函数也可以重载,而且 const 成员函数和非 const 成员函数可以构成重载:
运算符重载
函数重载的一个重要应用是运算符重载。我们可以为自定义类型重新定义运算符的行为:
运算符重载让我们能够以自然的方式操作自定义类型。我们将在后续章节中详细学习运算符重载。
函数重载是 C++ 的强大特性之一,它让我们能够用统一的接口处理不同类型的数据,使代码更加简洁易读。
习题
编写一个名为
print的重载函数系列,分别处理int、double、string和int数组的输出。为一个表示复数的结构体重载
+和-运算符。
Last updated