我有一个发出事件的事件发射器和处理事件的事件处理程序。我可以扩展Event
对象来创建不同的事件,比如AlarmEvent
,并扩展EventHandler
对象来创建AlarmEventHandler
。EventHandler
有一个函数HandleEvent(Event &event)
。这会给可能具有HandleEvent(AlarmEvent &event)
方法的子类带来问题。显然,这是两个不同的函数,所以这里不会发生重写。相反,我需要让HandleEvent
被子类覆盖。
我完全理解问题所在,因为每个EventHandler
都有不同的HandleEvent
签名,所以EventEmitter
总是使用基本EventHandler::HandleEvent
来处理事件。我认为通过使用Event &event
作为EventEmitter::Emit
的参数,它将知道它处理的是哪种类型的Event
,并选择正确的方法。
如何让我的EventEmitter
调用AlarmEventHandler::HandleEvent
而不是基方法EventHandler::HandleEvent
?
// Example program
#include <iostream>
#include <string>
#include <vector>
// event types
class Event {};
class AlarmEvent : public Event {};
// event handler
class EventHandler {
public:
virtual void HandleEvent(Event event);
};
void EventHandler::HandleEvent(Event event){
std::cout << "Handle event " << std::endl;
}
// alarm event handler
class AlarmEventHandler : public EventHandler {
public:
void HandleEvent(AlarmEvent event);
};
void AlarmEventHandler::HandleEvent(AlarmEvent event){
std::cout << "Handle alarm event " << std::endl;
}
// event emitter
class Emitter {
public:
std::vector<EventHandler*> handlers;
void Emit(Event &event);
};
void Emitter::Emit(Event &event){
for(size_t i = 0; i < this->handlers.size(); i++){
this->handlers[i]->HandleEvent(event);
}
}
int main()
{
AlarmEventHandler handler;
AlarmEvent event;
Emitter emitter;
emitter.handlers.push_back(&handler);
// problem:
// Handle event printed instead of Handle alarm event
emitter.Emit(event);
}
发布于 2020-01-22 04:07:39
使用dynamic_cast
!
因此,您的AlarmEventHandler
可能如下所示:
// alarm event handler
class AlarmEventHandler : public EventHandler {
public:
void HandleEvent(const Event &event); // Our polymorphic override
void HandleEvent(AlarmEvent event); // Our custom Alarm logic
};
void AlarmEventHandler::HandleEvent(const Event &event){
try {
HandleEvent(dynamic_cast<const AlarmEvent&>(event));
} catch(const std::exception& e) {
std::cerr << "I can't handle things that aren't AlarmEvents!" << std::endl;
}
}
void AlarmEventHandler::HandleEvent(const AlarmEvent &event){
std::cout << "Handle alarm event " << std::endl;
}
不过,要做到这一点,您需要让Event
成为一个多态类。所以你把析构函数设为virtual
class Event {
public: virtual ~Event() {} //Need this so Event is a polymorphic class
};
在这里查看它的运行:https://ideone.com/KMkLfq
发布于 2020-01-22 04:28:54
您没有重写HandleEvent()
,而是重载了它。
您需要一个指针或引用,以便能够利用动态分派而不必强制转换。
内联注释:
#include <iostream>
#include <string>
#include <vector>
// event types
class Event {
public:
virtual ~Event(); // make base destructor virtual
};
Event::~Event() {}
class AlarmEvent : public Event {};
// event handler
class EventHandler {
public:
virtual void HandleEvent(Event& event);
virtual ~EventHandler(); // virtual base destructor
};
EventHandler::~EventHandler() {}
void EventHandler::HandleEvent(Event& event){
std::cout << "Handle event " << std::endl;
}
// alarm event handler
class AlarmEventHandler : public EventHandler {
public:
//void HandleEvent(AlarmEvent& event); // overload, does not override
void HandleEvent(Event& event);
};
void AlarmEventHandler::HandleEvent(Event& event){
std::cout << "Handle alarm event " << std::endl;
}
// event emitter
class Emitter {
public:
Emitter() : handlers() {}
std::vector<EventHandler*> handlers;
void Emit(Event &event);
};
void Emitter::Emit(Event& event) {
for(size_t i = 0; i < this->handlers.size(); i++){
this->handlers[i]->HandleEvent(event);
}
}
int main() {
AlarmEventHandler handler;
AlarmEvent event;
Emitter emitter;
emitter.handlers.push_back(&handler);
emitter.Emit(event);
}
使用编译
g++ -std=c++98 -O3 -Wall -Wextra -Weffc++ -pedantic -pedantic-errors
输出:
Handle alarm event
https://stackoverflow.com/questions/59848372
复制相似问题