【问题标题】:Subscribe a button to trigger some function dynamically in C++?订阅按钮以在 C++ 中动态触发某些功能?
【发布时间】:2009-12-22 20:47:18
【问题描述】:

我正在尝试创建一个按钮类(抽象),以便我可以设置当我的程序加载时动态单击该按钮时将触发什么功能。

我想通过读取 XML 文件来构造我所有的按钮,这是为了避免代码复制,所以只有 1 个“通用”按钮类对我来说真的很有用。

我想知道您是否可以动态传递有关方法的必要信息,例如指向方法所有者和相关方法名称的指针,或者甚至更好的是直接指向方法的指针,以便按钮调用该函数/方法点击时?

【问题讨论】:

    标签: c++ user-interface abstraction


    【解决方案1】:

    由于指向函数的指针是运行时工件,因此您不能将其存储在离线配置中。我看到了两种可能符合您描述的解决方案:

    1. 将您的函数放入动态库并按名称加载它们 - 这样您的配置会将按钮映射到库路径/函数名称对,
    2. 在启动时建立命名函数指针的“注册表”,可能是一些哈希表,因此配置会将按钮映射到哈希键。

    根据经验,虽然我会说构建这样的设施通常是多余的,而且配置很快就会变得比应用程序本身更重。

    一些额外的指针:Boost.Signals、QT Signals、Command 和 Chain of Responsibility 设计模式。

    【讨论】:

      【解决方案2】:

      您可以在通用Button 类中创建SetFunctor 方法,该方法接受函数对象作为参数。然后创建一个Call 方法,该方法调用包装在函数对象中的函数。像这样的:

          template<typename FUNC>
          class Functor
          {
              typedef FUNC (*FC)();
              FC func;
          public:
              Functor( FC f ) : func(f) {}
              ~Functor() {}
              FUNC Call() { return func(); }
              FUNC operator()() const { return Call(); }
          };
      
          class Button
          {
              std::auto_ptr<Functor<void> > pfunc;
          public:
              Button() {}
              ~Button() {}
              void SetFunctor( void(*fc)() )
              {
                  pfunc.reset( new Functor<void>( fc ) ); // now owns ptr;
              }
      
              void Call()
              {
                  pfunc->Call();
              }
          };
      
          ...
          void changeColor()
          {
            // do work
          }
      
          Button obj;
          obj.SetFunctor( changeColor );
          obj.Call();
      

      当然,我本可以使用更好的智能指针和/或更好的技术,但这应该可以让您大致了解我所暗示的内容。还要注意,这个 Functor 对象只能接受没有参数的函数。您可以根据自己的喜好更改此设置。希望对你有帮助!

      更新:添加了一些修复。很抱歉!

      【讨论】:

      • 如果你能为此提供一些代码示例会很好吗? :)
      • 添加了一个例子。未经测试,但您应该能够从这里弄清楚...
      【解决方案3】:

      您正在寻找信号/槽模式。

      在 C++ 中,两个流行的选项是 boost signals 和 sigc。

      【讨论】:

      • 你忘了 Qt,尽管它需要预处理器,但它非常流行。
      【解决方案4】:

      在 C++ 中有几种方法可以将按钮链接到函数 - 您可以使用函数指针(这有点吓人),或者使用信号和插槽模式来提供函数指针的功能,并且类型安全性更高。

      至于在运行时基于配置文件连接函数指针或信号和槽,要优雅地做到这一点将需要反射,而 C++ 没有为您提供。我怀疑这将是丑陋的部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-08
        • 1970-01-01
        • 2021-07-01
        • 1970-01-01
        • 2021-05-05
        • 1970-01-01
        • 2013-06-09
        • 1970-01-01
        相关资源
        最近更新 更多