1

我正在制作一个快板游戏,其中按钮类应该是独立的,所以我将函数指针放在按钮对象内以用于 OnClick 事件。在项目的进行中,我一直将全局函数放在 MyButton 构造函数的参数中,一切正常 - 当我尝试在那里传递 Node::OnClick() 时出现了问题:

节点.h:

class Node {
private:
    static int _id;
    int id;
    bool active;
    std::vector<Node*> neighbours;
    std::vector<bool> mask;
public:
    Node();
    int getId();
    void addNeighbour(Node* neighbour);
    void OnClick();
    void Check();
    void Uncheck();
    bool isActive();
};

我的按钮.h:

class MyButton {
private:
    MyRectangle* boundingBox;
    ALLEGRO_BITMAP* image;
    void (*onClick)(void);
public:
    MyButton();
    MyButton(ALLEGRO_BITMAP* img, MyRectangle* boundingBox, void (*onClick)(void)); 
    MyButton(ALLEGRO_BITMAP* img, int x, int y, void (*onClick)(void)); 
    void Draw();
    void clickCheck(int x, int y);
};

主要的:

Node* current = graph->getNode(i);
buttons[i] = new MyButton(scarab1, button_coords[0]-27, button_coords[1]-27, current->OnClick);

错误:

error C3867: 'Node::OnClick': function call missing argument list; use '&Node::OnClick' to create a pointer to member

这段代码执行得很好:

buttons[i] = new MyButton(scarab1, button_coords[0]-27, button_coords[1]-27, &testOnClick);

一旦我将 &Node::OnClick 放入 ctor 参数中,如下所示:

buttons[i] = new MyButton(scarab1, button_coords[0]-27, button_coords[1]-27, &Node::OnClick);

然后我得到:

main.cpp(135): error C2664: 'MyButton::MyButton(ALLEGRO_BITMAP *,int,int,void (__cdecl *)(void))' : cannot convert parameter 4 from 'void (__thiscall Node::* )(void)' to 'void (__cdecl *)(void)'
4

1 回答 1

3

你的Node::OnClick功能是类型void (Node::*)(void)

您可能想研究使用mem_fn. (或mem_fun取决于您可以使用的内容。mem_fun已弃用并已替换为mem_fn

mem_fn(&Node::OnClick)void (*)(void)在这种情况下将返回一个类型的函数指针。(该类型在技术上未指定。)

哎呀,在这一点上,我建议一起忘记函数指针并调查std::function


好的,std::function这里的替代方案会更干净:

// Pass *current here
auto fn = std::bind(&Node::OnClick, class_instance);

上面的行将从绑定到类实例的成员函数中返回一个可调用对象。将其传递给您的函数,但不要使用函数指针,而是使用std::function<void(void)>.

于 2013-08-03T11:43:22.773 回答