Pregunta

Así que estoy trabajando en esta clase de gestión de eventos. Estoy almacenando una lista de punteros a funciones miembro de la firma void (Event*) donde evento es simplemente una estructura que almacena algunos datos aleatorios en el momento.

typedef boost::function<void(Event*)> Callback;
typedef vector<Callback> CallbackList;

class EventManager
{
public:
   template<typename T>
   void RegisterEventHandler(const std::string& type, void (T::*handler)(Event*), T* obj)
   {
      mCallbackList[type].push_back(boost::bind(handler, obj, _1));
   }

   void DispatchEvent(const std::string& type, Event* evt)
   {
      for(CallbackList::iterator it = mCallbackList[type].begin(); it != mCallbackList[type].end(); ++it)
      {
         Callback callback = (*it);
         callback(evt);
      }   
   }
private:
   hash_map<std::string, CallbackList> mCallbackList;
};

Me pregunto, si es posible para mí para derivar diferentes versiones del evento, y pasar punteros a esas funciones miembro dentro de esta clase? Actualmente estoy tratando de esto.

class MouseEvent : public Event
{
public:
   int testMouseData1;
   int testMouseData2;
   int testMouseData3;
};

class HelloWorld 
{
public:
   void Display(MouseEvent* evt)
   {
      cout << "Hello, world!" << endl;
   }
};


int main(void)
{
   MouseEvent* evt = new MouseEvent();

   HelloWorld* world = new HelloWorld();
   eventManager->RegisterEventHandler("testType", &HelloWorld::Display, world);

   return 0;
}

Esto me da el siguiente error en XCode.

  

Error: ninguna función coincidente para la llamada a 'EventManager::RegisterEventHandler(const char [9], void (HelloWorld::*)(MouseEvent*), HelloWorld*&)'

¿Sabe usted cómo me puede pasar con seguridad en un puntero que está esperando una clase derivada en su firma de la función? Gracias.

¿Fue útil?

Solución

Así que encontré una solución que parece estar funcionando para mí, pero no estoy seguro si es del todo seguro hacerlo. He cambiado el método RegisterEventHandler a votar todos los punteros de función que envío para el mismo tipo ...

 template<typename T1, typename T2>
   void RegisterEventHandler(const String& type, T1 handler, T2* obj)
   {
      void (T2::*evtHandler)(Event*) = (void (T2::*)(Event*)) (handler);
      mCallbackList[type].push_back(boost::bind(evtHandler, obj, _1));
   }

Ahora todo parece funcionar igual que yo pretendía originalmente. Pero estoy bastante nuevo en todo esto así que no estoy del todo seguro de si esto es una cosa segura a hacer. ¿Alguna idea? Gracias

Otros consejos

Si su prototipo de espera "Evento" tipo, entonces usted necesita para asegurarse de que la función void Display(MouseEvent* evt) está aceptando el tipo "Event". Así que cambiarlo a void Display(Event *evt) Luego dentro de la llamada puede encasillado de nuevo a un MouseEvent, en el supuesto de que la persona que llama aprobó una MouseEvent real, referenciado como "Event".

En segundo lugar, creo que es posible que tenga algunos otros problemas con la forma en la que está llamando RegisterEventHandler ya que está en una plantilla, pero no especifica el tipo de plantilla.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top