C++多态与模板接口场景下onError通用默认实现方案咨询
问题解答
方案2的合理性评估
方案2是完全合法可用的实现,这种多继承场景下派生类显式调用公共基类实现的委托方式是C++的常规操作,不存在设计缺陷。唯一的不足是当客户端类型较多时,每个派生类都要手动写一遍onError的桥接代码,会产生冗余。
更优的实现方案:添加模板中介层
你可以在ClientBase和具体客户端类之间新增一层模板类,统一完成IEventHandler的onError桥接,彻底消除重复代码:
// 新增模板中介层,统一实现onError桥接逻辑 template<class T_Event> class ClientEventHandler : public ClientBase, public IEventHandler<T_Event> { public: // 全局统一桥接onError到ClientBase的默认实现 void onError() override { ClientBase::onError(); } // onEvent留为纯虚方法,要求具体业务客户端实现 void onEvent(const T_Event& e) override = 0; }; // ClientBase补充onError的统一默认实现 class ClientBase { public: virtual void startReceiving() = 0; virtual void stopReceiving() { std::cout << "ClientBase::stopReceiving" << std::endl; } virtual void onError(){ std::cout << "ClientBase::onError" << std::endl; } };
改造后具体的客户端类可以简化为:
class ClientA : public ClientEventHandler<EventA> { public: void onEvent(const EventA& e) override { std::cout << "ClientA::onEvent - e.getData()= " << e.getData() << std::endl; }; void startReceiving() override { std::cout << "ClientA::startReceiving" << std::endl; }; }; class ClientB : public ClientEventHandler<EventB> { public: void onEvent(const EventB& e) override { std::cout << "ClientB::onEvent - e.getData()= " << e.getData() << std::endl; }; void startReceiving() override { std::cout << "ClientB::startReceiving" << std::endl; }; };
该方案的优势:
- 完全兼容现有逻辑:客户端类仍然同时是
ClientBase子类和对应IEventHandler子类,原有框架调用、容器存储逻辑不需要做任何修改 - 无冗余代码:
onError的桥接逻辑只在模板层实现一次,新增客户端类时不需要再重复编写 - 扩展性好:如果某个客户端需要自定义
onError逻辑,直接在子类重写即可,不影响全局默认实现 - 无额外开销:模板实例化在编译期完成,运行效率和手动编写桥接代码完全一致
如果当前客户端数量很少(仅2-3个),直接沿用方案2也完全合适,开发成本更低,不存在性能或维护隐患。
内容的提问来源于stack exchange,提问作者Amie89
相关产品推荐
相关产品推荐

