2012-05-12 23 views
1

エンジンでレベジエータクラスを作成するのに忙しかったですが、メンバ関数を別のメンバ関数のパラメータとして渡してしまいました。メンバ関数をメンバ関数のパラメータとして渡す

まず私は、typedefの

typedef void (LevelEditor::*CallFunctionPtr)(); 

は、その後、私は、ユーザーがhitregionに彼のマウスでクリックしたかどうかを確認するためにメンバ関数を作った作りました。そうであれば、別の関数を呼び出す必要があります。だから私は、その後

void LevelEditor::CheckClickCollision(HitRegion* region, CallFunctionPtr callFunctionPtr) 
{ 
    if(GAME_ENGINE->GetLButtonMouseState()) 
    { 
     if(!m_bIsLeftPressed && region->HitTest(m_MousePosition)) 
      (this->*callFunction)(); 

     m_bIsLeftPressed = true; 
    } 
    else 
     m_bIsLeftPressed = false; 
} 

LevelEditor.cpp

2つのパラメータ

LevelEditor.h

void CheckClickCollision(HitRegion* region, CallFunctionPtr callFunctionPtr); 

で私の最初のメンバ関数をしたIました2つの愚かな例のメンバ関数:

LevelEditor .h

void LevelUp(); 
void LevelDown(); 

LevelEditor.cpp

void LevelEditor::LevelUp() 
{ 
    ++m_iCurrentLevel; 
} 

void LevelEditor::LevelDown() 
{ 
    if(m_iCurrentLevel > 0) 
     --m_iCurrentLevel; 
    else 
     return; 
} 

そして今、私はヒットがあるかどうかをチェックするために、すべてのダニ、その関数を呼び出したいです。だから私のダニ機能に:

エラー:void型(LevelEditor :: *)()の引数 "型のパラメータと互換性がありません"

CheckClickCollision(m_LeftArrowRegionPtr, LevelDown); 
CheckClickCollision(m_RightArrowRegionPtr, LevelUp); 

そしてここで私はLevelDownとLevelup上のエラーを取得しますCallFunctionPtr *は」

いけない、別のものを試してみました。それを修正する方法を知っているものは何もしてみ

+1

これまでに 'std :: mem_fn'と考えられましたか? – chris

+0

これはまだ分かっていませんが、私はそれを探します。 Thnx;) – Thore

答えて

1

を働いた

CheckClickCollision(m_LeftArrowRegionPtr, &LevelEditor::LevelDown); 
CheckClickCollision(m_RightArrowRegionPtr, &LevelEditor::LevelUp); 
これをコールする

#include <stdio.h> 

class LevelEditor; 

typedef void (LevelEditor::*CallFunctionPtr)(); 

class LevelEditor 
{ 
public: 
    LevelEditor() {} 

    void CheckClickCollision(void* region, CallFunctionPtr callFunction) 
    { 
     (this->*callFunction)(); 
    } 

    void LevelUp() { printf("up\n"); } 
    void LevelDown() { printf("down\n"); } 

    void Test() 
    { 
     CheckClickCollision(NULL, &LevelEditor::LevelDown); 
     CheckClickCollision(NULL, &LevelEditor::LevelUp); 
    } 
}; 

int main() 
{ 
    LevelEditor e; 
    e.Test(); 

    return 0; 
} 

他の方法:あなたの便宜のため

が、ここでの作業サンプルです(コンパイラはGCC 4.7である)

あなたが std::functionstd::bind、またはラムダの場合を使用する必要が
void Test() 
    { 
     CallFunctionPtr p; 
     p = &LevelEditor::LevelDown; 
     CheckClickCollision(NULL, p); 
     p = &LevelEditor::LevelUp; 
     CheckClickCollision(NULL, p); 
    } 
+0

まだ同じエラーですが、今のところ& – Thore

+1

&? –

+0

いいえ、ちょうどLevelEditorへのエラーの変更 – Thore

0

サポートコンパイラがあります。

void LevelEditor::CheckClickCollision(HitRegion* region, std::function<void()> callFunction) 
{ 
    if(GAME_ENGINE->GetLButtonMouseState()) 
    { 
     if(!m_bIsLeftPressed && region->HitTest(m_MousePosition)) 
      callFunction(); 

     m_bIsLeftPressed = true; 
    } 
    else 
     m_bIsLeftPressed = false; 
} 

void Test() 
{ 
    // lambda 
    CheckClickCollision(NULL, [this] { LevelDown(); }); 
    // bind 
    CheckClickCollision(NULL, std::bind(&LevelEditor::LevelDown, this)); 
} 
+0

我々は少し近いです。関数は機能しますが、私が最初に呼び出す関数のみです。 LevelUpとLevelDownを行うと、LevelUpが機能します。 LevelDownとLevelUpを行うと、LevelDownが機能します。 – Thore

+0

これは、コードに別の問題があることを意味します。たとえば、衝突テスト(HitTest)は実際には失敗し、何も呼び出されません。 m_bIsLeftPressedを見てください。それはtrueに設定されています...もちろん、2番目の呼び出しは機能しません。 –

+0

あなたは私が間違っていることを理解しています。 LevelUpとLevelDownのヒット領域で100回クリックできます。 100回動作しますが、2つの機能のうち1つの場合にのみ機能します。または、LevelUpまたはLevelDownで機能します。 LevelUpの呼び出しがLevelDownの上に置かれている場合、それは動作するLevelUpです。 LevelDownがLevelUpの上に置かれている場合、LevelDownだけが機能します。私のヒット領域には何も問題はありません。 私はm_bIsLeftPressedを使用して1回のクリックしか持たない。マウスボタンが押されている場合、GAME_ENGINE-> GetLButtonMouseState()は常に真です。したがって、1回のクリックで1回の呼び出しを得るには、m_bIsLeftPressedを使用します。私はそれをテストしました。 – Thore

関連する問題