2

だから私はこのイベント管理クラスに取り組んでいます。署名のメンバー関数へのポインターのリストを保存していますvoid (Event*)。ここで、イベントは現時点でランダムなデータを保存する単なる構造体です。

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;
};

異なるバージョンの Event を派生させ、それらのメンバー関数へのポインターをこのクラスに渡すことができるかどうか疑問に思っています。現在、私はこれを試しています。

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;
}

これにより、XCode で次のエラーが発生します。

EventManager::RegisterEventHandler(const char [9], void (HelloWorld::*)(MouseEvent*), HelloWorld*&)エラー: ' ' の呼び出しに一致する関数がありません

関数シグネチャで派生クラスを期待しているポインターを安全に渡す方法を知っていますか? ありがとう。

4

2 に答える 2

2

だから私は自分のために働いていると思われる解決策を見つけましたが、それが完全に安全かどうかはわかりません. RegisterEventHandler メソッドを変更して、送信するすべての関数ポインターを同じ型にキャストしました...

 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));
   }

今では、すべてが当初の意図どおりに機能しているようです。しかし、私はこれらすべてにかなり慣れていないため、これが安全なことであるかどうかは完全にはわかりません. 何かご意見は?ありがとう

于 2010-02-06T18:37:37.647 に答える
1

void Display(MouseEvent* evt)プロトタイプが "Event" タイプを想定している場合、関数が " " タイプを受け入れることを確認する必要がありますEvent。したがって、呼び出し元が" " として参照される実際の を渡したと仮定すると、呼び出しvoid Display(Event *evt)内で型キャストして に戻すことができます。MouseEventMouseEventEvent

第二に、テンプレートにあるため、呼び出し方法に他の問題がある可能性があると思いますがRegisterEventHandler、テンプレートの種類を指定していません。

于 2010-02-06T17:40:23.097 に答える