c++ - 如何使用回调使工作简单的按钮类?

标签 c++ button

如何制作简单的按钮类以在按下时调用自定义函数。一些代码示例:

class Button
{
    public:
        Button();
        Draw();
        Press();
        SetCallback(void(*cback)());

    priate:
        void (*callback)();
}

void Button::SetCallback(void(*cback)())
{
    callback = cback;
}

class GameState
{
    ...
}

class MenuState : public GameState
{
    Button *btn;
}

class Game
{
    ...
}
bool Game::Init()
{
    std::unique_ptr<GameState> menu = std::unique_ptr<MenuState>(new MenuState);

}
void Game::PopState(){
        states.pop_back();
}

在此示例中如何将按钮中的回调设置为 Game::PopState() 函数。我需要 然后按下按钮调用 Game::PopState 函数。

最佳答案

你要找的是关于函数指针的教程,可以找到here .

如果您需要传递一个参数,您的按钮函数指针应该有一个指针或对您的 Game 对象的引用,因为成员函数需要引用(对哪个对象拥有函数调用)。如果您的 Game 类中的 popstate 函数是私有(private)的,您可能需要将其设为公共(public)函数或友元函数。

您应该能够通过将字符串引用替换为对 Game 对象的引用来修改下面的示例。如果您需要更通用的回调,请查看模板(更好但更复杂一点)或输入双关语(通常被认为是不好的做法)


#include <iostream>
#include <string>
class Button
{
    public:
        void SetCallback(void(*cback)(std::string&));
        void Press(std::string str){
          //Make sure some sort of check is done in order to prevent undefined behavior from a call
          if(callback != nullptr)
            callback(str);
        }
        Button(){
          callback = nullptr;
        }
    private:
        void (*callback)(std::string&);
};

void Button::SetCallback(void(*cback)(std::string&))
{
    callback = cback;
}
//Method 2 for calling function
void DoStuff(std::string& str){
  std::cout << str;
}

int main(void){

  Button btn;
  //Method 1 for calling function, replace body with Game.PopStates();
  auto foo = [](std::string& str){ std::cout<<str.size();};
  btn.SetCallback(foo);
  btn.Press("A");
  //Method 2 for calling function
  btn.SetCallback(&DoStuff);
  btn.Press("\nPressed Button");
  return 0;
}

Game 的函数指针应该是这样的:

void SetCallback(void(*cback)(Game&));

你可以这样调用它:

auto foo = [](Game& g){ g.DoStuffInClass(); };
  btn.SetCallback(foo);
  btn.Press(game);

上面的例子工作正常,通常是你需要做的,但是这篇文章 here更深入地了解成员函数指针。这篇文章的主要内容是 typedef 是另一种编写成员函数指针的方法,如下所示:

typedef int (Fred::*FredMemFn)(char x, float y); // Please do this!

但是,以上所有操作(当使用 PopStates 实现时)会将您的按钮回调锁定为使用 Game 对象调用的 void 函数,这会限制您使用按钮的能力。如果您希望允许在没有 Game 对象的情况下执行特殊情况,则可以使用指针而不是引用,但无论哪种方式,您的 Game 对象都必须找到某种方式放入您的回调中。

关于c++ - 如何使用回调使工作简单的按钮类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58329692/

相关文章:

c++ - 为什么我不能按原样将右值引用传递给 C++11 中的另一个函数?

java - Htmlunit Javascript 按钮/链接

wpf - 当用户在文本框中键入内容时如何启用按钮

c++ - 如何在 C++ 中创建原子枚举?

c++ - I/O 信号和处理程序

IE9 中的 CSS 按钮边缘

Android 后退按钮和进度对话框

css - Facebook 登录按钮位置

c++ - 如何在连续内存中多态地存储和访问来自同一继承层次结构的不同类型?

c++ - 对指针和 C++ 多态性的引用