2013-10-04 42 views
2

我對C++中的函數指針的概念相當陌生,所以我不知道如何正確編寫我的問題。請多多包涵。將StateMachine的狀態作爲參數傳遞給函數指針C++ OOP

基本上,我想要做的是創建一個Button對象,其構造函數接受函數指針作爲其參數。該函數指針指向一個將改變StateMachine狀態的函數。

下面是示例代碼(它不工作,和不相干位已經被剝離出來)

Button.h

#include "StateMachine.h" 

class Button 
{ 
private: 
    void (*m_onclickAction)(); //a data member 
public: 
    Button(void (*action)()); 
}; 

StateMachine.h(我沒有寫,我只是允許才能使用。所以應該會有用的代碼沒有問題,我不想對其進行修改)

#include <map> 

template<class E, class T> 
class StateMachine 
{ 
public: 
    typedef void (T::*CallbackOnInitialise)(); 
    typedef void (T::*CallbackOnExit)(); 
private:  
    T* m_pOwner; 
    E m_currentState; 

    // Maps to store function pointers to state functions. 
    std::map<E, CallbackOnInitialise> m_statesOnInitialise; 
    std::map<E, CallbackOnExit> m_statesOnExit; 

public: 
    StateMachine(T* pOwner, E emptyState) 
    { 
     m_currentState = emptyState; 
     m_pOwner = pOwner; 
    } 

    void ChangeState(E statenext) 
    { 
     //do something to change the state 
    } 
}; 

所以,在我的主程序類,我能夠做這樣的事

#include "Button.h" 
#include "StateMachine.h" 

//Code to instantiate an StateMachine object goes here 
Button* aButton = new Button(aStateMachine->ChangeState(NEW_STATE)); 

問題是我不能想辦法正確地傳遞NEW_STATE,這是因爲函數指針期待不帶參數的程序類中聲明枚舉。我嘗試過調整它,但沒有成功。

任何有關我應該怎麼做的建議?

回答

0

這裏有幾個問題。首先是在您的版本中,當您創建Button實例時,您的請致電ChangeState成員函數。第二個是m_onclickAction是一個指向函數的指針,與指向成員函數的指針不同。

爲此,我建議你看看std::functionstd::bind

class Button 
{ 
    std::function<void(int)> m_onclickAction; 

public: 
    Button(std::function<void(int)> action) { ... } 
}; 

然後你就可以像這樣創建按鈕:

Button* aButton = new Button(
    std::bind(&StateMachine::ChangeState, aStateMachine, NEW_STATE)); 
0

回調的boost :: bind()的和boost ::函數()是一個非常有用的工具。所以,你的Button類可能是這樣的:

class Button 
{ 
public: 
    typedef boost::function<void()> Callback; 
    Button(Callback clickAction); 
private: 
    Callback m_onclickAction; //a data member 
}; 

代碼傳遞的StateMachine方法與參數則是:

Button* aButton = new Button(boost::bind(&StateMachine::ChangeState, aStateMachine, NEW_STATE)); 

如果使用C++ 11可以更換的boost ::綁定性病::使用std :: function綁定和boost ::函數。

0

Tha庫有一個設計錯誤。

問題是函數指針只是C++中的函數指針(不是閉包),因此它沒有任何上下文。

如果您想要創建一個繪製藍色圓圈的按鈕,您將需要一個全局函數,該函數將繪製一個不帶參數的藍色圓圈。

如果想要另一個按鈕畫一個黃色的圓圈,你將需要畫一個黃色圓圈採取任何參數的另一次全球性的功能。

更具體的問題是,圖書館沒有任何辦法在按鈕保存所謂的「上下文」,以能夠通過你的代碼顏色使用畫圓。

C++ 11增加了一些提醒(因爲是很難在沒有垃圾收集任何語言來解決問題的壽命不是真實的東西),但他們都沒有裸露的函數指針有點封閉。

你想要做什麼是沒有,除非你使用一些不好的黑客爲the one you can see here試圖使用裸函數指針在C效仿std::bind改變Button類只是不可能的。

相關問題