Estoy intentando implementar un bus de eventos seguro. Estoy atascado con la función EventBus::subscribe
porque no acepta mi controlador de evento concreto. En una versión anterior tenía mi AbstractEventHandler
implementado como una clase abstracta solamente, sin que fuera una plantilla. No tuve ningún problema con esa implementación. Es por eso que asumo que el problema real es con la plantilla abstracta.La función C++ no acepta la implementación concreta
El siguiente código es una versión simplificada de mi implementación. El primer bloque consiste en el "esqueleto" del bus de eventos y sus clases requeridas, mientras que el segundo bloque muestra una implementación real del evento, el controlador de eventos y el principal.
El enum
contiene todos los diferentes eventos disponibles. El evento abstracto es la base de la cual se derivan todos los eventos concretos. El controlador de eventos es una plantilla abstracta con un evento como clase de plantilla para garantizar la seguridad de tipo. El bus de eventos es responsable de distribuir todos los eventos publicados a sus respectivos manejadores.
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
}
};
continuación son mis concreta controlador de eventos y el evento y el principal()
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);
}
Los rendimientos del compilador con decir un error que no hay una función coincidente para la llamada a
EventBus::subscribe(EVENT_TYPE, ConcreteEventHandler*)
y que los únicos candidatos son
void EventBus::subscribe(EVENT_TYPE, AbstractEventHandler<AbstractEvent>*)
¿Cómo puedo implementar mi método EventBus :: subscribe para aceptar implementaciones concretas de mi clase abstracta?
Actualización: Solución
me han cambiado la descripción del método de EventBus::subscribe
a la siguiente y que ahora trabaja muy bien:
template<typename T>
void subscribe(EVENT_TYPE type, AbstractEventHandler<T> *eventHandler) {
}
Gracias, Rohan, por sus consejos! Me ayudaron a encontrar esta solución.
+1 para una pregunta bien hecha. –