昨晚我开始为我的游戏实现我的 GUI 系统,我决定尝试使用函数指针来处理 gui 事件。我以前没有使用过它们,但能够得到一个基本的实现。但是,我想扩展 GUI 系统的可用性和“通用性”。目前,我在 protected 修饰符下的 GUI 父类(super class)中有一个函数指针。我在类中还有一个 getter(回调)和一个 setter(subscribeEvent)来为 gui 分配一个事件。目前看起来有点像这样:
class GUI
{
public:
…….
……
std::function<void()> callback() const { return eventCallback; }
void subscribeEvent(const std::function<void()>& callback)
{
eventCallback = callback;
}
protected:
std::function<void()> eventCallback;
};
要设置函数回调,您将 void 函数传递给 subscribeEvent,它工作正常。但是,您不能对任何函数使用作用域解析修饰符,传入的函数必须像这样是一个全局函数。
(MainGame.h):
void global();
class MainGame
{
public:
void Init();
void nonGlobal();
private:
std::vector<GUI*> _guis;
};
(MainGame.cpp):
void MainGame::Init()
{
Button* button = new Button(……); //< Button is a subclass of GUI
button->subscribeEvent(global); //< This works fine
button->subscribeEvent(MainGame::nonGlobal); //< This does not work saying something like “void(MainGame) is not of type void()”
_guis.pushBack(button);
}
void MainGame::nonGlobal()
{
……
}
void global()
{
……
}
有谁知道如何修改参数以允许传入任何类范围内的任何函数。这会很有帮助,因为我可以让按钮事件来自玩家、敌人、元素等类,而不是让每个处理函数都是全局的。我见过高级 gui 系统传递事件,例如“event(handlerFunction, classtype)”,因此您可以传递处理函数,然后传递处理函数所在的对象。这是我想采用的方法。
最佳答案
如果您将函数 MainGame::nonGlobal
设为静态,您的代码就可以运行:
class MainGame
{
public:
void Init();
static void nonGlobal();
private:
std::vector<GUI*> _guis;
};
你不能传递一个非静态成员函数的原因是因为成员函数有一个隐式的第一个参数(this
),在你的类型MainGame*
.因此,实际上您当前尝试传递的函数具有签名 void(MainGame*)
而不是 void()
。
或者,您可以使用 lambda 来绑定(bind) this
参数,而不是直接传递函数:
button->subscribeEvent([this](){nonGlobal();});
关于C++:如何将来自任何类的函数作为参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38354559/