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

Passing a member function as parameter of a member function

本文关键字:函数 成员 参数传递      更新时间:2023-10-16

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

首先我做了一个打字

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

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

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

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

LevelEditor.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 *" 的参数不兼容

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

尝试

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("upn"); }
    void LevelDown() { printf("downn"); }
    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);
    }

如果你有支持的编译器,你需要使用 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));
}