我正在设计一个简单的发布/订阅系统(基于Boost Signals2)。在此系统中,您可以通过EventManager::subscribe订阅特定类型的事件。然而,令人沮丧的是,每个订阅者都必须将const Event&转换为他们订阅的特定事件。有什么好的/优雅的方法来避免这个问题?我很高兴切换到一个非常不同的设计。
#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);
}发布于 2021-06-11 15:43:29
是的,这是典型的瓶颈模式,其中的多态性不适合您的需求。它使你可以将不同的数据从同一个洞中挤出来,然后再弄清楚它是什么。因此,您必须订阅某种字符串名称来“基本”事件,如下所示:
void subscribe(std::string type, std::function<void(const Event &)> subscriber); 您可能希望使用特定类型的处理程序订阅特定事件:
void subscribe(std::function<void(const SquareEvent &)> subscriber); 
void subscribe(std::function<void(const RoundEvent &)> subscriber); 或者你甚至想要一个通用的订阅,比如:
template<class E>
void subscribe(std::function<void(const E &)> subscriber) {
     // implement 
} 后者必须在header中实现。如果这样做,那么就不需要将EventA&转换为Event&,然后在处理程序Event&中将其转换回EventA&。
https://stackoverflow.com/questions/67932625
复制相似问题