Я пытаюсь реализовать типизированную шину событий.Я застрял с функцией 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) {
}
СпасибоРохан, за твои намеки!Они помогли мне найти это решение.