2016-07-13 73 views
0

我昨晚開始爲我的遊戲實現我的GUI系統,並決定嘗試使用函數指針來處理gui事件。我之前沒有使用它們,但能夠獲得基本的實現。但是,我想擴展GUI系統的可用性和「通用性」。目前,我在受保護的修飾符下的GUI超類中有一個函數指針。我還有一個getter(回調函數)和一個setter(subscribeEvent)來分配一個事件。目前,它看起來有點像這樣:C++:如何將任何類的函數作爲參數傳遞

class GUI 
{ 
public: 
    ……. 
    …… 
    std::function<void()> callback() const { return eventCallback; } 
    void subscribeEvent(const std::function<void()>& callback) 
    { 
     eventCallback = callback; 
    } 

protected: 
    std::function<void()> eventCallback; 
}; 

要設置一個回調函數,你在一個空函數subscribeEvent工作正常通過。然而,你不能在任何函數中使用範圍解析修飾符,傳入的函數必須是像這樣的全局函數。

(MainGame.h): 

void global(); 

class MainGame 
{ 
public: 
    void Init(); 
    void nonGlobal(); 

private: 
    std::vector<GUI*> _guis; 
}; 

(MainGame.cpp): 

void MainGame::Init() 
{ 
    Button* button = new Button(……); //< Button is a subclass of GUI 
    button->subscribeEvent(global); //< This works fine 
    button->subscribeEvent(MainGame::nonGlobal); //< This does not work saying something like 「void(MainGame) is not of type void()」 
    _guis.pushBack(button); 
} 

void MainGame::nonGlobal() 
{ 
…… 
} 

void global() 
{ 
…… 
} 

有誰知道如何修改參數,允許在任何類範圍的任何功能中進行傳遞。這將是有益的,因爲我可以有一個按鈕事件來自玩家,敵人,項目,沒有任何處理函數是全局的。我已經看到高級gui系統傳遞事件,如'event(handlerFunction,classtype)',所以你可以傳入處理函數,然後傳入一個處理函數駐留的對象。這是我想採用的一種方法。

+2

'button-> subscribeEvent([this](){nonGlobal();});' –

回答

1

,如果你做的功能MainGame::nonGlobal靜態您的代碼將工作:

class MainGame 
{ 
public: 
    void Init(); 
    static void nonGlobal(); 

private: 
    std::vector<GUI*> _guis; 
}; 

你不能傳遞一個非靜態成員函數的原因是因爲成員函數,在一個隱含的第一個參數(this)您的案例的類型MainGame*。所以實際上你目前試圖通過的函數有簽名void(MainGame*)而不是void()

或者,您也可以直接使用Lambda而不是傳遞函數this參數綁定:

button->subscribeEvent([this](){nonGlobal();}); 
0

更改此:

button->subscribeEvent(MainGame::nonGlobal); //< This does not work saying something like 「void(MainGame) is not of type void()」 

button->subscribeEvent(std::bind(&MainGame::nonGlobal, this)); 

有了這個改變你有的終身管理的另一個問題雖然。

+0

非常感謝!我繼續在subscribeEvent函數中實現了std :: bind功能,因此我可以在MainGame代碼中調用&MainGame :: nonGlobal而不使用std :: bind。我也使它通用,所以我可以包含帶參數的函數:std :: function callback()const {return eventCallback; } \t模板 \t空隙subscribeEvent(T實例,F FUNC,參數數量...參數) \t { \t \t呼叫臨時= {標準::綁定(FUNC ,instance,args ...)}; \t \t eventCallback = temp; \t} – Connor

相關問題