订阅按钮以在C ++中动态触发某些功能?

时间:2009-12-22 20:47:19

标签: c++ user-interface abstraction

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

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

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

4 个答案:

答案 0 :(得分: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对象只能接受没有参数的函数。您可以根据自己的喜好进行更改。我希望它有所帮助!

更新:添加了一些修复程序。对不起!

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:0)

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

在C ++中,两个流行的选项是boost signalssigc

答案 3 :(得分:0)

有几种方法可以将按钮链接到C ++中的函数 - 你可以使用函数指针(有些可怕),或者信号和插槽模式,它提供了更多类型安全的函数指针功能。 / p>

至于在运行时根据配置文件连接函数指针或信号和插槽,要优雅地执行此操作将需要反射,C ++不为您提供。我怀疑这将是丑陋的部分。