题目

编写程序,设计具有纯虚函数(virtual void func() = 0;)的抽象接口类(Interface)ILogger。展示抽象类无法被实例化(直接定义对象将引发编译器阻止)的契约强制性;设计具体的派生实现类 ConsoleLogger 与 FileLogger 必须完整实现所有的纯虚函数,否则派生类将继续保持为抽象类。通过统一接口驱动不同的日志持久化插件。

输入格式:无需外部输入。

输出格式:输出基于纯虚接口的抽象依赖注入与不同插件实现输出。

数据范围与约定:接口设计、面向接口编程契约与纯虚函数语法。

思路与算法

1. 纯虚函数的声明与意义
在虚函数声明末尾加上 = 0 即构成纯虚函数。它只定义方法签名规范(接口协议),不要求提供默认实现(但 C++ 允许为纯虚函数提供外部定义体)。

2. 抽象类的不可实例化约束
包含至少一个纯虚函数的类就是抽象类(Abstract Class)。尝试编写 ILogger logger; 会被编译器严厉报错。它存在的唯一目的就是作为基类被派生实现。

3. 依赖倒置原则(DIP)
高层业务模块只依赖抽象接口 ILogger&,而不直接依赖具体的 ConsoleLogger,实现了软件工程中高度解耦的插件式架构。

完整程序

#include <iostream>
#include <string>
#include <memory>
#include <vector>

// 纯虚抽象接口类(契约)
class ILogger {
public:
    virtual ~ILogger() = default; // 虚析构

    // 纯虚函数:派生类必须无条件提供实现
    virtual void log(const std::string& msg) = 0;
    virtual std::string getChannel() const = 0;
};

// 具体实现 1:控制台日志器
class ConsoleLogger : public ILogger {
public:
    void log(const std::string& msg) override {
        std::cout << "[控制台标准流] " << msg << "\n";
    }
    std::string getChannel() const override {
        return "STDOUT_CONSOLE";
    }
};

// 具体实现 2:文件模拟日志器
class MockFileLogger : public ILogger {
public:
    void log(const std::string& msg) override {
        std::cout << "[模拟持久化文件写入] >>> " << msg << "\n";
    }
    std::string getChannel() const override {
        return "FILE_APP_LOG";
    }
};

// 面向接口的高层服务,与底层日志具体实现完全解耦
void businessService(ILogger& logger, const std::string& task) {
    std::cout << ">>> 触发服务业务: \"" << task << "\" (通道: " << logger.getChannel() << ")\n";
    logger.log("业务 [" + task + "] 执行成功,状态码 200 OK");
}

int main() {
    ConsoleLogger console;
    MockFileLogger fileLog;

    std::cout << "--- 1. 注入控制台日志实现 ---\n";
    businessService(console, "UserLogin");

    std::cout << "\n--- 2. 注入文件日志实现 ---\n";
    businessService(fileLog, "OrderPayment");

    return 0;
}

运行示例

输出:

--- 1. 注入控制台日志实现 ---
>>> 触发服务业务: "UserLogin" (通道: STDOUT_CONSOLE)
[控制台标准流] 业务 [UserLogin] 执行成功,状态码 200 OK

--- 2. 注入文件日志实现 ---
>>> 触发服务业务: "OrderPayment" (通道: FILE_APP_LOG)
[模拟持久化文件写入] >>> 业务 [OrderPayment] 执行成功,状态码 200 OK