2012-05-12 196 views
1

我忙於在引擎中創建一個leveleditor類,但我堅持將成員函數作爲另一個成員函數的參數傳遞。傳遞成員函數作爲成員函數的參數

首先,我做了一個typedef

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

然後我做了一個成員函數來檢查用戶是否與他的一個hitregion鼠標點擊。如果是這樣,需要調用另一個函數。所以我我的第一個成員函數有兩個參數

LevelEditor.h

void CheckClickCollision(HitRegion* region, CallFunctionPtr callFunctionPtr); 

LevelEditor.cpp

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; 
} 

然後我有2個愚蠢的例子成員函數:

關卡編輯器.H

void LevelUp(); 
void LevelDown(); 

LevelEditor.cpp

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

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

現在我想調用該函數每一個刻度,以檢查是否存在命中。所以在我的蜱功能:

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

在這裏,我得到LevelDown和升級火錯誤:

錯誤:類型爲void(關卡編輯器:: *)()的說法「是與類型的參數不兼容」 CallFunctionPtr *」

不知道如何解決它。嘗試不同的東西,沒有什麼工作

+1

有沒有考慮過'std :: mem_fn'? – chris

+0

不知道這一點,但我會搜索它。 Thnx;) – Thore

回答

1

嘗試

CheckClickCollision(m_LeftArrowRegionPtr, &LevelEditor::LevelDown); 
CheckClickCollision(m_RightArrowRegionPtr, &LevelEditor::LevelUp); 

爲了您的方便,這裏的工作示例(編譯器GCC 4.7):

#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; 
} 

另一種方式來調用這個:

void Test() 
    { 
     CallFunctionPtr p; 
     p = &LevelEditor::LevelDown; 
     CheckClickCollision(NULL, p); 
     p = &LevelEditor::LevelUp; 
     CheckClickCollision(NULL, p); 
    } 
+0

同樣的錯誤,但現在在& – Thore

+1

而沒有&? –

+0

不,到關卡編輯器 – Thore

0

您需要使用std::functionstd::bind,或者如果lambda表達式你有一個支持編譯器。

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,然後...當然,第二個調用將不起作用。 –

+0

你明白我錯了。我可以在LevelUp和LevelDown的hitregion上點擊100次。它將工作100次,但僅限於兩種功能中的一種。或者它可以在LevelUp或LevelDown上運行。如果LevelUp的調用位於LevelDown之上,那麼LevelUp就會起作用。如果將LevelDown放在LevelUp之上,則只有LevelDown可以工作。我的襲擊地區沒有任何問題。 我使用m_bIsLeftPressed只有一次點擊。如果鼠標按鈕關閉,GAME_ENGINE-> GetLButtonMouseState()始終爲true,因此只需一次單擊即可獲得一次調用,我使用m_bIsLeftPressed。我測試過了。 – Thore

相關問題