我正忙于在引擎中创建一个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 *“类型的参数不兼容
不知道如何修复它。尝试了不同的事情,没有任何效果
答案 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::function
和std::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));
}