0

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

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

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

4

4 回答 4

1

SetFunctor您可以在泛型类中创建一个方法Button,该方法接受一个函数对象作为参数。然后创建一个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 对象只能接受没有参数的函数。您可以根据自己的喜好更改此设置。我希望它有帮助!

更新:添加了一些修复。对于那个很抱歉!

于 2009-12-22T21:04:06.263 回答
1

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

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

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

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

于 2009-12-22T21:07:25.233 回答
0

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

在 C++ 中,两个流行的选项是boost 信号sigc

于 2009-12-22T21:00:31.940 回答
0

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

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

于 2009-12-22T21:05:59.473 回答