0

我对 Qt 非常熟悉,而且我知道我们不能有类似的合成器,因为我们这里没有 MOC 部分。但是,我试图在我的类中进行信号创建管理以简化信号的声明及其与信号的连接。

这就是我现在正在做的示意图


    class Foo
    {
       public:
          void connectMove(boost::signal<void(int)>::slot_type slot)
          void connectRotate(boost::signal<void(double)>::slot_type slot)

       private:
          boost::signal<void(int)> m_signalMove;
          boost::signal<void(double)> m_signalRotate;
    };

这基本上是我想做的(大写=缺失部分)



    class SignalManager 
    {
       public:
          typedef boost::unrodered_map<std::string, GENERIC_SIGNAL *> MapSignal;
       public:
          template <typename Sig>
          bool connect(const std::string& strSignalName, boost::signal<Sig>::slot_type slot)
          {
             // simplyfied... :
             (*m_mapSignal.find(strSignalName))->connect(slot);
          }

          template <typename Sig>
          bool disconnect(const std::string& strSignalName, boost::signal<Sig>::slot_type slot)
          {
             // simplyfied... :
             (*m_mapSignal.find(strSignalName))->disconnect(slot);
          }

       protected:
          bool call(const std::string& strSignalName, SIGNAL_ARGS)
          {
             (*m_mapSignal.find(strSignalName))(SIGNAL_ARGS);
          }

          template <typename Sig>
          void delareSignal(const std::string& strSignalName)
          {
             m_mapSignals.insert(MapSignal::value_type(strSignalName, new boost::signal<Sig>()));
          }

          void destroySignal(const std::string& strSignalName)
          {
             // simplyfied... :
             auto it = m_mapSignal.find(strSignalName);
             delete *it;
             m_mapSignal.erase(it);
          }

       private:
          MapSignal m_mapSignals;
    };

    class Foo : public SignalManager
    {
       public:
          Foo(void)
          {
             this->declareSignal<void(int)>("Move");
             this->declareSignal<void(double)>("Rotate");
          }
    };


    class Other : public boost::signals::trackable
    {
       public:
          Other(Foo *p)
          {
             p->connect("Move", &Other::onMove);
             p->connect("Rotate", &Other::onRotate);
          }

          void onMove(int i)
          {
             /* ... */
          }

          void onRotate(double d)
          {
             /* ... */
          }
    };


我想我可以用 boost::functions_traits<> 解决“SIGNAL_ARGS”部分,但我不知道如何绕过抽象信号类型。

1/我想要的有可能吗?

2/这是一个好方法吗?(我知道由于 unordered_map.find 会产生一些开销,尤其是当我使用 this->call("signalname", ...) 时,但我认为它不应该太重要)

3/如果这不可能或不是一个好方法,你还有其他建议吗?

4

1 回答 1

1

我通过包装boost::signals并使用 aboost::shared_ptr<IWrapperSignal>而不是我的GENERIC_SIGNAL.

参数问题也使用boost::function_traits<T>::arg_type.

我不知道这是否是最好的方法,但它工作正常,并且用户在继承 this 的类中声明信号更简单SignalManager

于 2011-12-12T18:14:39.903 回答