由于签名不同,调用了错误的 child class 函数
Wrong child class function being called due to signature difference
我有一个发射事件的事件发射器和处理事件的事件处理程序。我可以扩展 Event
object 来制作不同的事件,例如 AlarmEvent
,并扩展 EventHandler
object 来制作 AlarmEventHandler
。 EventHandler
有一个函数 HandleEvent(Event &event)
。这会导致 child class 可能有 HandleEvent(AlarmEvent &event)
方法的问题。显然,这是两个不同的功能,因此这里没有发生重写。我需要 HandleEvent
被 child class.
覆盖
我完全理解问题是每个 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);
}
使用 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
成为多态 class。所以你使析构函数 virtual
:
class Event {
public: virtual ~Event() {} //Need this so Event is a polymorphic class
};
在此处查看 运行:https://ideone.com/KMkLfq
您没有覆盖 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
我有一个发射事件的事件发射器和处理事件的事件处理程序。我可以扩展 Event
object 来制作不同的事件,例如 AlarmEvent
,并扩展 EventHandler
object 来制作 AlarmEventHandler
。 EventHandler
有一个函数 HandleEvent(Event &event)
。这会导致 child class 可能有 HandleEvent(AlarmEvent &event)
方法的问题。显然,这是两个不同的功能,因此这里没有发生重写。我需要 HandleEvent
被 child class.
我完全理解问题是每个 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);
}
使用 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
成为多态 class。所以你使析构函数 virtual
:
class Event {
public: virtual ~Event() {} //Need this so Event is a polymorphic class
};
在此处查看 运行:https://ideone.com/KMkLfq
您没有覆盖 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