非标准语法 - 使用 & 创建指向成员的指针:C++函数指向成员的指针



我正在创建一个spirograph应用程序,并且有一个简单的GUI类,它可以生成和管理按钮-您可以在单击按钮时使用自定义函数指针来调用这些函数。

我还有一个Engine类,它管理螺旋图和GUI按钮的绘制。

我想创建一个按钮,它有一个指向引擎类中成员函数的指针,但我一直收到一个错误。

当我试图用Engine类中的函数指针创建一个按钮时,就会出现错误。

正如Frank在评论中所建议的(谢谢(

class Engine;
typedef void(Engine::*enginefunc)(void);
class Engine
{
void cb();
void register_callback(enginefunc ptr);
void foo() {
register_callback(cb);
}
};

这是我的发动机等级:

发动机.h

class Engine : public GUI
{
private:
//....
public:
Engine(sf::Vector2f* mousepos);
//...
//...inherited a function from GUI called addbutton.
};
Engine::Engine(sf::Vector2f* mousepos)
:GUI(mousepos)
{   

//THIS IS THE LINE WHICH PRODUCES THE ERROR. I AM TRYING TO PASS THE CHANGE POINT FUNCTION INTO THE GUI BUTTON.
addbutton(sf::Vector2f{ 100,50 }, sf::Vector2f{ 200,100 }, "Button", sf::Color::Red, sf::Color::Blue, changepoint); 
}

这是GUI.h(包含导致错误的addbutton函数(

class Engine;
typedef void(Engine::* enginefunc)(void);
class GUI : public sf::Drawable
{
private:    
//...
public:
GUI(sf::Vector2f* mousepos);
void addbutton(const sf::Vector2f& position, const sf::Vector2f& dimension, const std::string& text, sf::Color initcolor, sf::Color highlightcolor, enginefunc ptr);
//other member funcs..
};

这是GUI::addbutton函数

void GUI::addbutton(const sf::Vector2f& pos, const sf::Vector2f& size, const std::string& text, sf::Color before, sf::Color after, enginefunc ptr)
{
buttons.emplace_back(pos, size, text, before, after, ptr);
}

因此,addbutton函数创建了一个GUIButton类,该类存储函数ptr。单击按钮时,函数指针将通过std::invoke调用。

这是我的GUIButton.h

class Engine;
typedef void(Engine::*enginefunc)(void);
class GUIButton :  public sf::RectangleShape
{
public:
GUIButton(const sf::Vector2f& position, const sf::Vector2f& size, const std::string& text, sf::Color initcolor, sf::Color highlightcolor, enginefunc ptr);
void action(Engine& e);
//other members...
private:
//other members...
enginefunc actionptr;
};

如您所见,enginefunc GUIButton::actionptr是按下按钮时将进行操作的函数指针。

下面是GUIButton::action((函数,它调用函数:

void GUIButton::action(Engine& e)
{
if (actionptr != nullptr)
{
std::invoke(actionptr, e);
}
}

我不明白我做错了什么。我知道指向成员函数的指针必须绑定到特定的对象,这就是为什么我将Engine对象作为引用。

有什么建议吗?

您应该只使用std::function。在这种情况下,这里的最佳实践将要求使用lambda来绑定this

相当于你的代码:

class Engine;
typedef void(Engine::*enginefunc)(void);
class Engine
{
Engine();
void changepoint();
void addbutton(enginefunc ptr);
};
Engine::Engine() {
addbutton(changepoint);
}

成为:

class Engine
{
Engine();
void changepoint();
void addbutton(std::function<void()> ptr);
};
Engine::Engine() {
addbutton([this](){changepoint();});
}

最新更新