将成员函数作为成员函数的参数传递

时间:2012-05-12 19:23:31

标签: c++ class function pointers member

我正忙于在引擎中创建一个leveleditor类,但我仍然坚持将成员函数作为另一个成员函数的参数传递。

首先我做了一个typedef

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

然后我创建了一个成员函数来检查用户是否用鼠标点击了hitregion。如果是这样,则需要调用另一个函数。所以我的第一个成员函数有2个参数

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

然后我有两个愚蠢的示例成员函数:

LevelEditor.h

void LevelUp();
void LevelDown();

LevelEditor.cpp

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

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

现在我想在每个刻度上调用该函数来检查是否有命中。所以在我的tick函数中:

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

在这里,我得到LevelDown和Levelup的错误:

错误:void类型的参数(LevelEditor :: *)()“与”CallFunctionPtr *“类型的参数不兼容

不知道如何修复它。尝试了不同的事情,没有任何效果

2 个答案:

答案 0 :(得分: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);
    }

答案 1 :(得分:0)

如果您有支持的编译器,则需要使用std::functionstd::bind或lambdas。

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