练习:通过基类指针实现动态绑定¶
任务描述¶
设计 Message 基类及 EmailMessage、SmsMessage 派生类,通过 Message* 调用同名虚函数。
相关知识¶
虚函数经由基类指针或引用调用时,运行时根据对象实际类型选择派生类覆盖版本。
静态绑定与动态绑定¶
普通成员函数按指针或引用的静态类型调用;声明为 virtual 后,Message* 调用 send() 将在运行时分派到 EmailMessage 或 SmsMessage 的覆盖实现。
override¶
派生类的 send 应写为 void send() const override。override 使编译器检查函数签名,防止遗漏 const 等原因导致函数隐藏。
编程要求¶
Message声明虚函数send() const和虚析构函数。- 两个派生类分别输出
发送邮件、发送短信。 test使用Message*数组调用send()并断言输出顺序。- 基类应提供虚析构函数,即使本题的对象在栈上创建。
- 两个派生类的
send函数必须使用override,并保持const属性与基类一致。
待完成代码¶
#include <cassert>
#include <iostream>
#include <sstream>
// TODO:定义三个类
void test() {
EmailMessage email;
SmsMessage sms;
Message* messages[] = {&email, &sms};
std::ostringstream output;
std::streambuf* oldBuffer = std::cout.rdbuf(output.rdbuf());
// TODO:通过基类指针调用 send
std::cout.rdbuf(oldBuffer);
assert(output.str() == "发送邮件\n发送短信\n");
}
int main() {
test();
std::cout << "本关测试通过" << std::endl;
return 0;
}
测试说明¶
预期输出依次为“发送邮件”“发送短信”。调用循环不得根据对象类型编写条件分支,应只调用 messages[i]->send()。
开始你的任务吧,祝你成功!