首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在发布/订阅系统中避免static_cast?(C++)

如何在发布/订阅系统中避免static_cast?(C++)
EN

Stack Overflow用户
提问于 2021-06-11 15:06:44
回答 1查看 64关注 0票数 1

我正在设计一个简单的发布/订阅系统(基于Boost Signals2)。在此系统中,您可以通过EventManager::subscribe订阅特定类型的事件。然而,令人沮丧的是,每个订阅者都必须将const Event&转换为他们订阅的特定事件。有什么好的/优雅的方法来避免这个问题?我很高兴切换到一个非常不同的设计。

代码语言:javascript
复制
#include <iostream>
#include <functional>
#include <string>

class Event {
  virtual std::string get_type() = 0;
};

class EventA : public Event {
  std::string get_type() override {
    return "EVENT_A";
  }
  int get_foo() {
    return 5;
  }
};

class EventManager {
 public:
  void publish_event(const Event &e);
  void subscribe(std::string type, std::function<void(const Event &)> subscriber);
};

int main() {
  EventManager event_manager;
  event_manager.subscribe("EVENT_A", [&](const Event &e) {
    const EventA &event_a = static_cast<const EventA &>(e); // how can avoid cast here?
    // do stuff with event_a
  });

  EventA event_a;
  event_manager.publish_event(event_a);
}
EN

回答 1

Stack Overflow用户

发布于 2021-06-11 15:43:29

是的,这是典型的瓶颈模式,其中的多态性不适合您的需求。它使你可以将不同的数据从同一个洞中挤出来,然后再弄清楚它是什么。因此,您必须订阅某种字符串名称来“基本”事件,如下所示:

代码语言:javascript
复制
void subscribe(std::string type, std::function<void(const Event &)> subscriber); 

您可能希望使用特定类型的处理程序订阅特定事件:

代码语言:javascript
复制
void subscribe(std::function<void(const SquareEvent &)> subscriber); 
void subscribe(std::function<void(const RoundEvent &)> subscriber); 

或者你甚至想要一个通用的订阅,比如:

代码语言:javascript
复制
template<class E>
void subscribe(std::function<void(const E &)> subscriber) {
     // implement 
} 

后者必须在header中实现。如果这样做,那么就不需要将EventA&转换为Event&,然后在处理程序Event&中将其转换回EventA&

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67932625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档