函数重载
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 57 课,共 104 课。
函数重载允许你定义多个名称相同但参数列表不同的函数。编译器会根据你传入的参数选择正确的版本。这是编译时多态的一种重要形式。
要让重载生效,函数的签名必须不同:参数的数量、类型,或两者都不同:
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
Calculator calc;
calc.add(5, 3); // 调用 add(int, int)
calc.add(2.5, 3.7); // 调用 add(double, double)
calc.add(1, 2, 3); // 调用 add(int, int, int)编译器会检查每次调用,并将其匹配到合适的重载。这一过程完全在编译时进行,因此不会产生运行时开销。
重要:仅靠返回类型无法区分重载函数。下面的代码会导致编译器错误:
int getValue();
double getValue(); // 错误:不能仅根据返回类型进行重载函数重载能让代码更直观。你不必创建 addInts、addDoubles 和 addThreeInts 这样的不同名称,而是使用一个有意义的名称,让编译器处理其余部分。
挑战
简单让我们来创建一个消息格式化类,展示函数重载的强大之处。你将创建一个 Formatter 类,其中包含多个 format() 方法,用来处理不同类型的输入,让编译器根据你传入的内容选择正确的版本。
你需要将代码分别写在两个文件中:
Formatter.h:定义一个Formatter类,其中包含重载的format()方法,用来处理不同的情况:- 一个接收单个
std::string并打印:Message: <text>的方法 - 一个接收
std::string和int优先级的方法,打印:[Priority <priority>] <text> - 一个接收
std::string和double时间戳的方法,打印:[<timestamp>s] <text> - 一个接收三个
std::string参数(sender、receiver、message)并打印:From <sender> to <receiver>: <message>的方法
format():编译器会根据参数选择正确的方法。- 一个接收单个
main.cpp:读取 4 项输入(每项单独占一行):- 一段简单的消息文本
- 一个优先级(整数)
- 一个时间戳(double)
- 一个发送者名称
创建一个
Formatter对象,并演示全部 4 个重载方法:- 仅使用消息文本调用
format() - 使用消息文本和优先级调用
format() - 使用消息文本和时间戳调用
format() - 使用发送者、将 "Admin" 作为接收者以及消息文本调用
format()
例如,输入 System ready、3、12.5 和 Server 时:
Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System ready注意,你调用了 4 次同名方法 format(),但每次调用都会根据参数的类型和数量执行不同版本。这就是编译时多态:程序运行前,编译器就会确定使用哪个重载版本。
亲手试试
#include <iostream>
#include <string>
#include "Formatter.h"
using namespace std;
int main() {
// 读取输入
string message;
getline(cin, message);
int priority;
cin >> priority;
double timestamp;
cin >> timestamp;
cin.ignore();
string sender;
getline(cin, sender);
// TODO: 创建一个 Formatter 对象
// TODO: 仅用消息文本调用 format()
// TODO: 用消息文本和 priority 调用 format()
// TODO: 用消息文本和 timestamp 调用 format()
// TODO: 用 sender、作为接收者的 "Admin" 和消息文本调用 format()
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器