2016-07-13 8 views
0

私は昨夜私のゲームのGUIシステムを実装し始めました。私はGUIポインタを使ってGUIイベントを処理しようとしました。私は前にそれらを使用していませんでしたが、基本的な実装を得ることができました。しかし、GUIシステムの使いやすさと汎用性を広げたいと思います。現在、私は保護された修飾子の下でGUIスーパークラスに関数ポインタを持っています。また、geti(コールバック)とsetter(subscribeEvent)をクラス内に持ち、GUIイベントを割り当てます。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にvoid関数に渡し、関数コールバックを設定するには:それは、現在、このような小さなものになります。しかし、どのような関数でもスコープ解決修飾子を使うことはできません。渡される関数はグローバル関数でなければなりません。

(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()の代わりにvoid(MainGame*)という署名があります。

また、あなたの代わりに関数を直接渡すのラムダを使用することによってthisパラメータをバインドすることができます。

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

変更この:

これにより
button->subscribeEvent(std::bind(&MainGame::nonGlobal, this)); 

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

をあなたはの生涯管理の別の問題を持っていますしかし。

+0

大変感謝!私は、mainGameコードでstd :: bindなしで&MainGame :: nonGlobalを呼び出すことができるように、実装されたstd :: bind関数をsubscribeEvent関数に追加しました。私もそれを一般的なものにして、引数を持つ関数を含めることができました:std :: function callback()const {return eventCallback; } \tテンプレート<型名T、型名F、型名...のArgs> \t空隙subscribeEvent(Tインスタンス、FのFUNC、Argsの...引数) \t {\t \tコールTEMP = {STD ::バインド(FUNC 、インスタンス、args ...)}; \t \t eventCallback = temp; \t} – Connor

関連する問題