2013-03-02 234 views
0

我正在構建一個簡單的監聽器/回調機制,用於我當前的實驗項目。而我堅持實施一個容器結構似乎應該是指針向量的矢量。我選擇這種方式是因爲我想讓根矢量簡單地讓事件類型的KEY讓我們說是一個枚舉(int),然後在這個鍵上我想存儲指向此事件類型的可用方法的指針向量。在邏輯表示是這樣的:矢量矢量(成員)函數指針

[EVENT_TYPE_QUIT] 
       [ptr1] 
       [ptr2] 
       [ptr3] 
       [ptr4] 
       [....] 
[EVENT_TYPE_HELLO] 
       [....] 
       [....] 

typedef enum { 
    EVENT_TYPE_QUIT, 
    EVENT_TYPE_HELLO, 
    ... 
} EventType; 

所以簡化實現看起來是這樣的(這是在現實中的模板,但想象T是任何用戶類型可以映射事件)。

class EventMapper { 
    ... 

    typedef void (T::*functionPtr)(); // simple pointer to T member function with no args. 

    std::vector< std::vector<functionPtr> > eventCallbacks; 

    void mapEvent(const EventType type, functionPtr callback) { 

     // here i need to map type to callback 
     // each type can have multiple callbacks 
     // T can have only distinct event types as "key" 

     // this i tried but doesn't work 

     eventCallbacks[type].push_back(callback); 

    } 

    ... 
} 

預期的實現看起來是這樣的:

EventMapper<SupaDupaClass> mapper; 
mapper.mapEvent(EVENT_TYPE_HELLO, &SupaDupaClass::didYouSayHello); 

等等

我真的想用向量,而不是地圖,方便獨特的密鑰分配? 謝謝

回答

1

如果我讀了你的代碼,你正在訪問一個未初始化的條目。

你應該首先初始化與空載體的eventCallbacks,像

eventCallbacks.assign(10,的std ::向量())

1

您可以使用std::map到EVENT_TYPE映射到的矢量回調。並考慮使用std::function而不是函數指針來獲得靈活性。

一種可能的實現是:

#include <vector> 
#include <map> 
#include <functional> 
#include <iostream> 

enum class event_type 
{ 
    event_one, 
    event_two 
}; 

void func1() { std::cout << "func1" << std::endl; } 
class my_listener { public: void func() { std::cout << "my_listener::func" << std::endl; } }; 

int main() 
{ 
    std::map<event_type, std::vector<std::function<void()>>> m; 

    my_listener lst; 
    m[event_type::event_one].push_back(std::bind(&my_listener::func, lst)); 
    m[event_type::event_one].push_back(&func1); 

    // invoke callbacks (may be used in the code that raises events) 
    for(auto& kv : m) 
    { 
     for(auto& f : kv.second) { 
      f(); 
     } 
    } 

    return 0; 
} 

編輯: 您可以考慮使用Boost.Signals2庫。