跳转至

练习:通过基类指针实现动态绑定


任务描述

设计 Message 基类及 EmailMessageSmsMessage 派生类,通过 Message* 调用同名虚函数。

相关知识

虚函数经由基类指针或引用调用时,运行时根据对象实际类型选择派生类覆盖版本。

静态绑定与动态绑定

普通成员函数按指针或引用的静态类型调用;声明为 virtual 后,Message* 调用 send() 将在运行时分派到 EmailMessageSmsMessage 的覆盖实现。

override

派生类的 send 应写为 void send() const overrideoverride 使编译器检查函数签名,防止遗漏 const 等原因导致函数隐藏。

编程要求

  1. Message 声明虚函数 send() const 和虚析构函数。
  2. 两个派生类分别输出 发送邮件发送短信
  3. test 使用 Message* 数组调用 send() 并断言输出顺序。
  4. 基类应提供虚析构函数,即使本题的对象在栈上创建。
  5. 两个派生类的 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()


开始你的任务吧,祝你成功!