我目前正在学习c++,我正在使用SFML/TGUI开发我的第一个游戏。我试过创建一个函数来创建一个按钮,当按下按钮时,它会调用一个函数。为了使按钮创建器更智能、更多版本,我将其设置为接受一个对象指针和一个函数指针作为参数。当按钮被按下时,我希望它能够从传递给它的对象调用成员函数。还应该指出的是,我让它工作了一段时间,但后来我改变了一些东西,现在它不工作。
在main.cpp中,我创建了一个gui和一个指向这个gui的指针。然后我将指针传递到我的Utility类,它由静态变量和函数组成:
//Create gui object
tgui::GuiSFML gui{ window };
//Create pointer to gui object
tgui::GuiSFML* guiPointer = &gui;
//Pass guiPointer into Utility class
Utility::setup_getGuiPointer(guiPointer);
这就是我的实用程序类中的内容:
//Static gui pointer in Utility
static tgui::GuiSFML* guiPointer;
//Passes gui pointer from main into Utility
static void Utility::setup_getGuiPointer(tgui::GuiSFML* passedGuiPointer)
{
guiPointer = passedGuiPointer;
}
我的实用程序类中的创建按钮函数如下所示:
//Takes arguments: ObjectPtr, FunctionPtr, Size, Pos and Text to create button
template<typename Class>
inline tgui::Button::Ptr& Utility::u_createButton(Class* object, void(Class::* functionPointer)(tgui::GuiSFML* guiPointer, tgui::Button::Ptr& button), tgui::Layout2d size, tgui::Layout2d position, std::string buttonText)
{
//Creates the button
tgui::Button::Ptr button = tgui::Button::create(buttonText);
//Sets size and position
button->setSize(size);
button->setPosition(position);
//Adds button to gui
guiPointer->add(button);
//Sets onPress on the button to call the passed function from the passed objects,
//passing the gui pointer and button pointer into this function.
button->onPress([&]() { (object->*functionPointer)(guiPointer, button); });
//Returns button pointer if it's needed before onPress.
return button;
}
现在,我可以在任何类中使用以下行创建一个自定义按钮:
Utility::u_createButton(this, &ClassName::FunctionName, size, position, text;
我在我的一个类中创建了一个按钮,我传递一个指针的函数是:
void ClassName::FunctionName(tgui::GuiSFML* guiPointer, tgui::Button::Ptr& button)
{
std::cout << "Button Pressed" << std::endl;
//The reson behind the passed arguments is so that the function itself can delete
//the button after use if needed using the following line:
//guiPointer->remove(button);
}
当我运行它时,它会创建一个按钮,但当我按下它时会出现以下错误:
Unhandled exception at 0x85EEB600 in GUI_SFML_Template.exe: 0xC0000005: Access violation executing location 0x00000000.
The current stack frame was not found in a loaded module. Source cannot be shown for this location.
我不明白为什么我会得到这个错误,尽管我相信这与我的对象和函数在没有正确访问的情况下试图写入gui有关。如果有人能帮助我,我将不胜感激。
1条答案
按热度按时间a8jjtwal1#
你的lambda是通过引用捕获的,当按钮被按下时,它捕获引用的所有局部变量都会导致未定义的行为,因为局部变量将超出范围。您应该按值捕获:
一般来说,通过引用捕获所有对象的lambda表达式只在声明它们的函数中使用是安全的,不应该长期存储。