Sto tentando di implementare un bus eventi di tipo typesable. Sono bloccato con la funzione EventBus::subscribe
perché non accetta il mio gestore di eventi concreti. In una versione precedente avevo il mio AbstractEventHandler
implementato solo come una classe astratta, senza che fosse un modello. Non ho avuto problemi con questa implementazione. Ecco perché presumo che il problema reale sia con il modello astratto.La funzione C++ non accetta l'implementazione concreta
Il codice seguente è una versione ridotta della mia implementazione. Il primo blocco è costituito dallo "scheletro" del bus eventi e dalle sue classi richieste mentre il secondo blocco mostra un'implementazione effettiva dell'evento, del gestore di eventi e del main.
Il enum
contiene tutti i diversi eventi disponibili. L'evento astratto è la base della quale derivano tutti gli eventi concreti. Il gestore eventi è un modello astratto con un evento come classe modello per garantire la sicurezza del tipo. Il bus eventi è responsabile della distribuzione di tutti gli eventi pubblicati ai rispettivi gestori.
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
}
};
Qui di seguito sono il mio gestore di eventi e l'evento concreto e il principale()
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);
}
il compilatore ritorna con un errore dicendo che non v'è alcuna funzione di corrispondenza per la chiamata al
EventBus::subscribe(EVENT_TYPE, ConcreteEventHandler*)
e che gli unici candidati sono
void EventBus::subscribe(EVENT_TYPE, AbstractEventHandler<AbstractEvent>*)
Come posso implementare il mio metodo EventBus :: subscribe per accettare implementazioni concrete della mia classe astratta?
Aggiornamento: Soluzione
ho cambiato la descrizione del metodo di EventBus::subscribe
al seguente ed ora funziona bene:
template<typename T>
void subscribe(EVENT_TYPE type, AbstractEventHandler<T> *eventHandler) {
}
Grazie, Rohan, per i vostri suggerimenti! Mi hanno aiutato a trovare questa soluzione.
+1 per una domanda ben fatta. –