【发布时间】:2021-11-06 12:59:23
【问题描述】:
问题
假设我有一些模拟器库,它从我这里获取一些对象(也称为事件处理程序)并通过调用它们的 handle_event(Event) 方法为这些对象生成事件。该库为我提供了以下类:
class Event {}; // Base class for all events
// All event classes are derived from `Event`
class SomeParticularEvent : public Event {}; // Some event class
class AnotherParticularEvent : public Event {}; // Some event class
// Object aka event handler. I should inherit this class and then give objects to the simulator
class AbstractEventHandler
{
public:
virtual void handle_event(Event) = 0;
};
我想实现一个以不同方式处理不同事件的对象。我想出的第一个代码如下:
#include <iostream>
class MyObject : public AbstractEventHandler
{
public:
void actual_handle_event(SomeParticularEvent)
{
std::cout << "`SomeParticularEvent` occurred\n";
}
void actual_handle_event(AnotherParticularEvent)
{
std::cout << "`AnotherParticularEvent` occurred\n";
}
void actual_handle_event(Event e)
{
std::cerr << "Unknown event type occurred\n";
}
virtual void handle_event(Event e) override
{
actual_handle_event(e);
}
};
С 出乎我的意料,MyObject::handle_event(Event) 将始终调用MyObject::actual_handle_event(Event),而不管e 的动态类型如何。
我的问题是:实现MyObject 的正确方法是什么(最好是可以轻松添加新的事件类型)?
所有代码放在一起
#include <iostream>
class Event {}; // Base class for all events
// All event classes are derived from `Event`
class SomeParticularEvent : public Event {}; // Some event class
class AnotherParticularEvent : public Event {}; // Some event class
class AbstractEventHandler
{
public:
virtual void handle_event(Event) = 0;
};
class MyObject : public AbstractEventHandler
{
public:
void actual_handle_event(SomeParticularEvent)
{
std::cout << "`SomeParticularEvent` occurred\n";
}
void actual_handle_event(AnotherParticularEvent)
{
std::cout << "`AnotherParticularEvent` occurred\n";
}
void actual_handle_event(Event e)
{
std::cerr << "Unknown event type occurred\n";
}
virtual void handle_event(Event e) override
{
actual_handle_event(e);
}
};
int main()
{
MyObject o{};
o.handle_event(SomeParticularEvent{}); // Prints "Unknown event type occurred"
}
其他问题
是否也可以创建一个派生自MyObject 的类并实现附加 事件处理程序(不覆盖旧的,但添加对新事件的支持)而不重写handle_event 中的方法派生类?
【问题讨论】:
-
void handle_event(Event e)按值获取参数,执行对象切片。因此,无论原始对象的类型是什么,您将始终只有一个Event