c++成员函数指针,boost::信号

C++ member function pointer, boost::signals

本文关键字:boost 信号 指针 成员 函数 c++      更新时间:2023-10-16

我有以下情况,(在代码中更好)

    class Foo
    {
private:
       typedef boost::signal<void ()> Signal;
       Signal signal;
public:
       void Register_SignalFunction(const Signal::slot_type& slot);
       void Unregister_SignalFunction(const Signal::slog_type& slot);
    }
    class OtherFoo
    {
       Foo foo;
public:
       OtherFoo()
       {
            foo.Register_SignalFunction(&OnSignal)    //I know I can't do this that is precisely my question.
       }
       void OnSignal();  //what to do when signal fires
     }  

所以问题是,我如何传递一个'成员函数'指针到寄存器方法。还有,这样可以吗?我想要/需要的是某种委托注册系统,所以如果有人能给我指出正确的方向,我会很感激。

通常使用boost bind:

foo.Register_SignalFunction (boost::绑定(及OtherFoo:: OnSignal));

这是怎么回事?: -)

信号的connect方法接受一个函子。这是一个实现()操作符的对象。Bind接受函数指针(指向自由函数或成员函数),并返回一个签名正确的函子。

使用Boost::Signals处理c++事件的完整示例

:

boost::function和boost::bind是如何工作的

断开一个信号,将connect的返回值存储到a:

boost::signals::connection

然后调用disconnect方法

通常你会这样做:

void Register_SignalFunction(const boost::function<void()> &slot) {
    signal += slot;
}

或者,作为inline函数:

template<typename T>
void Register_SignalFunction(T &slot) {
    signal += slot;
}

去掉boost::function的间接层后,后者可能会稍微有效一些——但前提是boost::signal内部不使用boost::function(这很可能)。所以用你喜欢的,真的。

我得到了它的工作后,尝试了很多,这是代码:

GraphicsDeviceManager
{
  private:
      typedef boost::signal<void ()> DeviceLost;
      DeviceLost deviceLost;
  public:
      Register_DeviceLostHandler(const boost::function<void ()> &handler)
      {
          deviceLost.connect(slot);
      }
      Unregister_DeviceLostHandler(const boost::function<void ()> &handler)
      {
          //deviceLost.disconnect(slot); 
      }
}
class GameBase
{
  private:
    GraphicsDeviceManager* graphics;
   public:
       GameBase()
       {
          graphics = new GraphicsDeviceManager();
          graphics->Register_DeviceLostHandler(boost::bind(&GameBase::OnDeviceLost, this));
       }
       void OnDeviceLost()
       {
           //do some stuff
       }
}

好吧,这段代码工作正常,有一个例外,如果我取消注释deviceLost.disconnect(handler)语句,我收到编译错误,如:错误C266 "boost::operator ==": 4个重载有类似的转换。

为什么会这样呢?你知道还有其他方法可以完成我正在尝试的事情吗?

如果有人想要一个完整的例子:

#include <iostream>
#include <boost/signals2/signal.hpp>
#include <boost/bind.hpp>
#include <boost/optional/optional_io.hpp>
#define registerEvent_(A)   registerEvent(boost::bind(A, this, _1, _2))
struct A
{
    typedef boost::signals2::signal<int (int &, int &)> EventSignal;
    typedef EventSignal::slot_type SlotType;
    void registerEvent(const SlotType & slot);
    void triggerAll(int& a1, int& a2);
    EventSignal signal_;
};
void A::registerEvent(const SlotType & slot) { signal_.connect(slot); }
void A::triggerAll(int& a1, int& a2) {std::cout << signal_(a1, a2) << "n";}
struct B : public A
{
    B();
    int myFunc(int& a1, int& a2);
};
B::B() {
#ifdef WITHMACRO
    registerEvent_(&B::myFunc);
#else
    registerEvent(boost::bind(&B::myFunc, this, _1, _2));
#endif
}
int B::myFunc(int& a1, int& a2) { return a1 + a2 + 1; }
int main()
{
    int a1 = 2;
    int a2 = 3;
    B b;
    b.triggerAll(a1, a2);
}