You need to enable JavaScript to run this app. C++ InputReactor事件接收类冗余事件虚函数优化方案咨询
优惠活动
大模型
产品
解决方案
定价
更多

C++ InputReactor事件接收类冗余事件虚函数优化方案咨询

优化方案1:CRTP静态分发+统一虚函数入口

该方案只保留基类的单个虚函数作为事件入口,所有事件的路由逻辑仅编写一次,完全消除十多个重复虚函数声明的冗余,同时保留原有的子类按需重写事件处理函数的使用习惯。

// 先补充EVENTS枚举的定义示例
enum class EVENTS {
    QUIT, LEFT, RIGHT, UP, DOWN, AXISUPD, OK, CANCEL, SHIFT, CTRL, MAX_EVENTS
};

// 基础基类
class InputReactor
{
public:
    InputReactor(Input* input_) : m_input(input_) {}

    // 仅保留1个虚函数作为事件总入口
    virtual void on_input(EVENTS ev, float scale_) = 0;

    std::vector<EVENTS> subscribed_at;

    void setInputEnabled(bool inputEnabled_) { m_inputEnabled = inputEnabled_; }
    bool isInputEnabled() { return m_inputEnabled; }

    virtual ~InputReactor()
    {
        for (EVENTS ev : subscribed_at)
        {
            m_input->unsubscribe(ev, this);
        }
    }

protected:
    Input* m_input = nullptr;
    bool m_inputEnabled = false;
};

// CRTP中间层,统一实现事件路由逻辑,所有子类复用
template<typename Derived>
class InputReactorCRTP : public InputReactor
{
public:
    using InputReactor::InputReactor;

    void on_input(EVENTS ev, float scale_) override {
        // 统一处理输入启停控制,符合需求
        if (!isInputEnabled()) return;
        switch(ev) {
            case EVENTS::QUIT: static_cast<Derived*>(this)->input_quit(scale_); break;
            case EVENTS::LEFT: static_cast<Derived*>(this)->input_left(scale_); break;
            case EVENTS::RIGHT: static_cast<Derived*>(this)->input_right(scale_); break;
            case EVENTS::UP: static_cast<Derived*>(this)->input_up(scale_); break;
            case EVENTS::DOWN: static_cast<Derived*>(this)->input_down(scale_); break;
            case EVENTS::AXISUPD: static_cast<Derived*>(this)->input_axisupd(scale_); break;
            case EVENTS::OK: static_cast<Derived*>(this)->input_ok(scale_); break;
            case EVENTS::CANCEL: static_cast<Derived*>(this)->input_cancel(scale_); break;
            case EVENTS::SHIFT: static_cast<Derived*>(this)->input_shift(scale_); break;
            case EVENTS::CTRL: static_cast<Derived*>(this)->input_ctrl(scale_); break;
            default: break;
        }
    }

    // 提供所有事件的默认空实现,子类不需要处理的事件无需重写
    void input_quit(float scale_) {}
    void input_left(float scale_) {}
    void input_right(float scale_) {}
    void input_up(float scale_) {}
    void input_down(float scale_) {}
    void input_axisupd(float scale_) {}
    void input_ok(float scale_) {}
    void input_cancel(float scale_) {}
    void input_shift(float scale_) {}
    void input_ctrl(float scale_) {}
};

子类使用方式和原有逻辑几乎完全兼容,仅需修改继承方式:

class MyReactor : public InputReactorCRTP<MyReactor>
{
public:
    using InputReactorCRTP::InputReactorCRTP;

    // 仅需要重写自身需要处理的事件即可
    void input_quit(float scale_) {
        // 自定义退出逻辑
    }
    void input_ok(float scale_) {
        // 自定义确认逻辑
    }
};

优化方案2:回调注册机制,完全消除虚函数

如果不需要继承重写的模式,可以直接用回调表实现,代码冗余更低,运行开销更小:

class InputReactor
{
public:
    InputReactor(Input* input_) : m_input(input_) {}

    // 事件注册接口
    template<EVENTS ev, typename Func>
    void register_callback(Func&& func) {
        m_callbacks[static_cast<size_t>(ev)] = std::forward<Func>(func);
        subscribed_at.push_back(ev);
    }

    // Input类调用的事件触发入口
    void trigger(EVENTS ev, float scale_) {
        if (!m_inputEnabled) return;
        auto& cb = m_callbacks[static_cast<size_t>(ev)];
        if (cb) cb(scale_);
    }

    std::vector<EVENTS> subscribed_at;

    void setInputEnabled(bool inputEnabled_) { m_inputEnabled = inputEnabled_; }
    bool isInputEnabled() { return m_inputEnabled; }

    virtual ~InputReactor()
    {
        for (EVENTS ev : subscribed_at)
        {
            m_input->unsubscribe(ev, this);
        }
    }

private:
    Input* m_input = nullptr;
    bool m_inputEnabled = false;
    std::array<std::function<void(float)>, static_cast<size_t>(EVENTS::MAX_EVENTS)> m_callbacks;
};

子类使用示例:

class MyReactor : public InputReactor
{
public:
    MyReactor(Input* input) : InputReactor(input) {
        // 需要处理什么事件就注册什么,无需冗余声明
        register_callback<EVENTS::QUIT>([this](float scale) {
            // 退出逻辑
        });
        register_callback<EVENTS::OK>([this](float scale) {
            // 确认逻辑
        });
    }
};

内容的提问来源于stack exchange,提问作者SavedowW

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 09:36:09