2012-05-12 151 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

相关问题