Я пытаюсь реализовать типизированную шину событий. Я застрял с функцией EventBus::subscribe
, потому что она не принимает мой конкретный обработчик событий. В более ранней версии мой AbstractEventHandler
был реализован только как абстрактный класс, без шаблона. У меня не было проблем с этой реализацией. Вот почему я предполагаю, что реальная проблема связана с абстрактным шаблоном.
Приведенный ниже код представляет собой урезанную версию моей реализации. Первый блок состоит из «скелета» шины событий и необходимых для нее классов, тогда как второй блок показывает реальную реализацию события, обработчик события и главное.
Перечисление enum
содержит все доступные события. Абстрактное событие является основой, из которой выводятся все конкретные события. Обработчик событий — это абстрактный шаблон с событием в качестве класса шаблона для обеспечения безопасности типов. Шина событий отвечает за распределение всех опубликованных событий среди соответствующих обработчиков.
enum EVENT_TYPE
{
ON_EVENT_1,
ON_EVENT_2
};
class AbstractEvent
{
public:
AbstractEvent() {};
virtual ~AbstractEvent() {};
virtual EVENT_TYPE type() = 0;
};
template<class T>
class AbstractEventHandler
{
public:
AbstractEventHandler() {};
virtual ~AbstractEventHandler() {};
virtual void on_event(T *event) = 0;
};
class EventBus
{
public:
EventBus() {};
virtual ~EventBus() {};
void subscribe(EVENT_TYPE type,
AbstractEventHandler<AbstractEvent> *eventHandler) {
// Add handler to vector for further use
}
void publish(AbstractEvent *event) {
// send event to each handler in respective vector
}
};
Ниже приведены мое конкретное событие и обработчик событий, а также функция main().
class ConcreteEvent : public AbstractEvent
{
public:
ConcreteEvent() {};
virtual ~ConcreteEvent() {};
EVENT_TYPE type() {
return ON_EVENT_1;
};
};
class ConcreteEventHandler : public AbstractEventHandler<ConcreteEvent>
{
public:
ConcreteEventHandler() {}
virtual ~ConcreteEventHandler() {};
void on_event(ConcreteEvent *event) {
// Do something
};
};
int main()
{
EventBus *eventBus = new EventBus();
ConcreteEventHandler handler = ConcreteEventHandler();
// This failes!
eventBus->subscribe(ON_EVENT_1, &handler);
}
Компилятор возвращает сообщение об ошибке, говорящее о том, что нет подходящей функции для вызова
EventBus::subscribe(EVENT_TYPE, ConcreteEventHandler*)
и что единственными кандидатами являются
void EventBus::subscribe(EVENT_TYPE, AbstractEventHandler<AbstractEvent>*)
Как я могу реализовать мой метод EventBus::subscribe для принятия конкретных реализаций моего абстрактного класса?
Обновление: Решение
Я изменил описание метода EventBus::subscribe
на следующее, и теперь он отлично работает:
template<typename T>
void subscribe(EVENT_TYPE type, AbstractEventHandler<T> *eventHandler) {
}
Спасибо, Рохан, за подсказки! Они помогли мне найти это решение.