1

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

首先我做了一个typedef

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

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

关卡编辑器.h

void CheckClickCollision(HitRegion* region, CallFunctionPtr callFunctionPtr);

关卡编辑器.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;   
}

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

关卡编辑器.h

void LevelUp();
void LevelDown();

关卡编辑器.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 和 Levelup 的错误:

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

不知道如何解决。尝试了不同的东西,没有任何效果

4

2 回答 2

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);
    }
于 2012-05-12T19:28:38.593 回答
0

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

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));
}
于 2012-05-12T19:48:07.960 回答