17、函数重载
函数重载是C++的一项重要特性,通过函数重载,可以在同一个作用域内定义多个同名函数,但这些函数的参数列表必须不同(参数类型、参数个数或参数顺序不同)。
函数重载的规则
- 函数名相同: 重载的函数必须使用相同的函数名。
- 参数列表不同: 重载的函数必须有不同的参数列表,包括参数类型、参数个数或参数顺序。
- 返回值类型不影响重载: 仅返回值类型不同,不能构成函数重载。
函数重载的解析
当调用一个重载函数时,编译器会根据实际传递的参数类型、个数和顺序,选择最匹配的函数版本进行调用,如果找不到最匹配的,编译器会认为有歧义,报错。
示例代码:
#include <iostream>
using namespace std;
// 1. 参数个数不同
void print(int a) {
cout << "Printing an integer: " << a << endl;
}
void print(int a, int b) {
cout << "Printing two integers: " << a << ", " << b << endl;
}
// 2. 参数类型不同
void print(double a) {
cout << "Printing a double: " << a << endl;
}
void print(const string& str) {
cout << "Printing a string: " << str << endl;
}
// 3. 参数顺序不同
void print(int a, double b) {
cout << "Printing an integer and a double: " << a << ", " << b << endl;
}
void print(double a, int b) {
cout << "Printing a double and an integer: " << a << ", " << b << endl;
}
int main() {
print(10); // 调用 void print(int a)
print(10, 20); // 调用 void print(int a, int b)
print(3.14); // 调用 void print(double a)
print("Hello"); // 调用 void print(const string& str)
print(10, 3.14); // 调用 void print(int a, double b)
print(3.14, 10); // 调用 void print(double a, int b)
return 0;
}
进阶知识点
运算符重载: 运算符重载本质上也是函数重载,它允许为用户自定义类型定义运算符的行为。
在C++中,参数类型是否 const不会产生函数重载。这是因为 const 修饰符作用于参数时,只是限制了函数内部对参数值的修改,而不会改变参数的类型本身。
因此,以下两个函数声明会被认为是重复定义,而不是重载:
void func(int a); // 1
void func(const int a); // 2: 错误,重复定义,不是重载
编译器会将上述两个函数视为完全相同的函数签名,因此会导致编译错误。
const 修饰值参数
对于值传递的参数(如 int a),const 只是限制函数内部不能修改参数的值,但不会影响函数的外部行为。因此,以下两个函数声明是等价的:
void func(int a); // 1
void func(const int a); // 2: 与 1 等价
编译器会将它们视为相同的函数签名,因此无法重载。
const 修饰指针或引用参数
对于指针或引用参数,const 的位置不同会产生不同的语义,因此可以形成重载:
const修饰指针指向的内容:void func(int* p); // 1: 接受普通指针 void func(const int* p); // 2: 接受指向常量的指针这两个函数可以重载,因为参数类型不同(
int*和const int*)。
const修饰引用:void func(int& r); // 1: 接受普通引用 void func(const int& r); // 2: 接受常量引用这两个函数也可以重载,因为参数类型不同(
int&和const int&)。
const 修饰成员函数
对于类的成员函数,const 修饰的是成员函数本身,而不是参数。这种 const 会影响函数签名,因此可以形成重载:
class MyClass {
public:
void func() { std::cout << "Non-const func\n"; } // 1
void func() const { std::cout << "Const func\n"; } // 2
};
这里,func() 和 func() const 是两个不同的函数,可以重载。调用时,编译器会根据对象的 const 属性选择正确的版本:
MyClass obj;
const MyClass constObj;
obj.func(); // 调用 void func()
constObj.func(); // 调用 void func() const
练习
编写一个程序,定义三个重载函数
max(),分别用于求两个整数、两个浮点数和三个整数中的最大值。编写一个程序,定义一个函数模板
swap(),用于交换两个变量的值,并使用该模板交换两个整数、两个浮点数和两个字符串的值。编写一个程序,定义一个类
Point,表示二维平面上的点,并重载+运算符,实现两个点的加法运算。以下代码是否能编译通过?如果不能,为什么?
void func(int a); void func(const int a);
编写一个程序,定义一个函数
print,使其能够重载以下调用:print(int* p)print(const int* p)print(int& r)print(const int& r)
定义一个类
String,并重载operator[],使其支持以下调用:char& operator[](int index);const char& operator[](int index) const;





