MST

星途 面试题库

面试题:C++类成员函数作为回调函数在复杂架构中的应用

假设你正在参与一个大型的C++项目,该项目采用分层架构,在某一层中需要将类成员函数作为回调函数传递到另一层使用,同时要考虑到可维护性、扩展性以及性能优化。请详细描述你的设计思路,包括类的设计、回调函数的传递方式、如何处理不同层之间的依赖关系等,并给出关键代码片段。
14.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

类的设计

  1. 定义回调接口类
    • 创建一个纯虚基类作为回调接口,不同的回调实现类继承自该接口。这样可以实现多态,方便根据不同需求进行扩展。
    • 例如:
class CallbackInterface {
public:
    virtual void callbackFunction() = 0;
    virtual ~CallbackInterface() = default;
};
  1. 包含回调函数的类
    • 在需要提供回调函数的类中,定义成员函数作为回调的具体实现,并保存一个指向回调接口类的指针或智能指针。
    • 例如:
class CallerClass {
private:
    std::unique_ptr<CallbackInterface> callback;
public:
    void setCallback(std::unique_ptr<CallbackInterface> cb) {
        callback = std::move(cb);
    }
    void doSomething() {
        if (callback) {
            callback->callbackFunction();
        }
    }
};
  1. 回调实现类
    • 继承自回调接口类,实现具体的回调逻辑。
    • 例如:
class CallbackImpl : public CallbackInterface {
public:
    void callbackFunction() override {
        // 具体的回调逻辑代码
        std::cout << "Callback function executed." << std::endl;
    }
};

回调函数的传递方式

  1. 使用指针或智能指针
    • 如上述CallerClass中使用std::unique_ptr<CallbackInterface>来保存回调对象指针。在设置回调时,通过setCallback函数传递一个实现了CallbackInterface的对象指针或智能指针。
    • 示例代码:
CallerClass caller;
std::unique_ptr<CallbackInterface> impl = std::make_unique<CallbackImpl>();
caller.setCallback(std::move(impl));
caller.doSomething();

处理不同层之间的依赖关系

  1. 依赖倒置原则

    • 高层模块不应该依赖低层模块,二者都应该依赖抽象。在本设计中,CallerClass(高层模块)依赖CallbackInterface(抽象),而不是具体的CallbackImpl(低层模块)。这样如果需要更换回调实现,只需要创建新的继承自CallbackInterface的类,而不需要修改CallerClass的代码。
  2. 接口隔离原则

    • CallbackInterface只提供必要的回调函数接口,避免了不必要的接口依赖。不同层之间通过这个简洁的接口进行交互,提高了可维护性和扩展性。
  3. 使用依赖注入

    • 通过setCallback函数将回调对象注入到CallerClass中,而不是在CallerClass内部直接创建具体的回调对象。这样可以在运行时灵活地替换不同的回调实现,增强了扩展性。