簡體   English   中英

C ++成員函數指針,boost :: signals

[英]C++ member function pointer, boost::signals

我有以下情況,(代碼效果更好)

    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
     }  

所以問題是,如何將“成員函數”指針傳遞給Register方法。 還可以嗎 我想要/需要的是某種代表注冊系統,所以如果沒有人可以指出正確的方向,我將不勝感激。 提前感謝。

您通常會使用Boost綁定:

foo.Register_SignalFunction(boost :: bind(&OtherFoo :: OnSignal,this));

這里發生了什么? :-)

信號的連接方法需要一個函子。 那是一個實現()運算符的對象。 bind獲取函數指針(指向自由函數或成員函數),並返回具有正確簽名的函子。

另請參閱此處:

使用Boost :: Signals進行C ++事件的完整示例

和這里:

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

要斷開信號存儲,請將返回值從connect連接到:

boost::signals::connection

然后調用該方法的斷開連接。

通常,您會:

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

或者,作為內聯函數:

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

通過刪除間接boost::function具有的層,后者可能會稍微更有效率-但僅假設boost::signal在內部不使用boost::function (可能會使用)。 因此,請使用您喜歡的任何一種。

如果有人想舉一個完整的例子:

#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);
}

我嘗試了很多之后就可以正常工作了,下面是代碼:

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個重載具有相似的轉換。

那么,為什么會這樣呢? 您是否知道其他方法來完成我正在嘗試的工作?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM