Boost.orgでこれに対処しているチュートリアルを知っています: Boost.org Signals Tutorial そこの例にはインクルードファイルは示されておらず、コードの一部のセクションは少しあいまいです。
ここに私が必要なものがあります:
ClassAは複数のイベント/シグナルを発生させます
ClassBはこれらのイベントをサブスクライブします(複数のクラスがサブスクライブできます)
私のプロジェクトには、これらのメッセージを処理してUI(wxFrames)に通知するビジネスクラスにイベントを発生させる下位レベルのメッセージハンドラクラスがあります。私はこれらすべてがどのように結ばれるかを知る必要があります(どの順序、誰が誰を呼び出すかなど)。
コードベースの例を次に示します。単純化されているため、コンパイルされることを保証しませんが、近いはずです。サブロケーションはクラスA、Slot1はクラスBです。このようなスロットが多数あり、各スロットは信号の異なるサブセットにサブスクライブします。このスキームを使用する利点は、サブロケーションがスロットについて何も知らないこと、およびスロットが継承階層の一部である必要がなく、関心のあるスロットの機能のみを実装する必要があることです。これを使用して、非常にシンプルなインターフェイスでシステムにカスタム機能を追加します。
Sublocation.h
class Sublocation
{
public:
typedef boost::signal<void (Time, Time)> ContactSignal;
typedef boost::signal<void ()> EndOfSimSignal;
void endOfSim();
void addPerson(Time t, Interactor::Ptr i);
Connection addSignalContact(const ContactSignal::slot_type& slot) const;
Connection addSignalEndOfSim(const EndOfSimSignal::slot_type& slot) const;
private:
mutable ContactSignal fSigContact;
mutable EndOfSimSignal fSigEndOfSim;
};
Sublocation.C
void Sublocation::endOfSim()
{
fSigEndOfSim();
}
Sublocation::Connection Sublocation::addSignalContact(const ContactSignal::slot_type& slot) const
{
return fSigContact.connect(slot);
}
Sublocation::Connection Sublocation::addSignalEndOfSim(const EndOfSimSignal::slot_type& slot) const
{
return fSigEndOfSim.connect(slot);
}
Sublocation::Sublocation()
{
Slot1* slot1 = new Slot1(*this);
Slot2* slot2 = new Slot2(*this);
}
void Sublocation::addPerson(Time t, Interactor::Ptr i)
{
// compute t1
fSigOnContact(t, t1);
// ...
}
Slot1.h
class Slot1
{
public:
Slot1(const Sublocation& subloc);
void onContact(Time t1, Time t2);
void onEndOfSim();
private:
const Sublocation& fSubloc;
};
Slot1.C
Slot1::Slot1(const Sublocation& subloc)
: fSubloc(subloc)
{
subloc.addSignalContact(boost::bind(&Slot1::onContact, this, _1, _2));
subloc.addSignalEndSim(boost::bind(&Slot1::onEndSim, this));
}
void Slot1::onEndOfSim()
{
// ...
}
void Slot1::onContact(Time lastUpdate, Time t)
{
// ...
}
boost/libs/signals/example を見ましたか?
QTのようなBoostは、信号とスロットの独自の実装を提供します。以下は、その実装のいくつかの例です。
名前空間の信号およびスロット接続
GStreamerという名前空間を検討してください
namespace GStremer
{
void init()
{
....
}
}
信号を作成してトリガーする方法は次のとおりです
#include<boost/signal.hpp>
...
boost::signal<void ()> sigInit;
sigInit.connect(GStreamer::init);
sigInit(); //trigger the signal
クラスの信号とスロットの接続
次のシグネチャを持つfunc1およびfunc2という関数を持つGSTAdaptorというクラスを考えます
void GSTAdaptor::func1()
{
...
}
void GSTAdaptor::func2(int x)
{
...
}
信号を作成してトリガーする方法は次のとおりです
#include<boost/signal.hpp>
#include<boost/bind.hpp>
...
GSTAdaptor g;
boost::signal<void ()> sigFunc1;
boost::signal<void (int)> sigFunc2;
sigFunc1.connect(boost::bind(&GSTAdaptor::func1, &g);
sigFunc2.connect(boost::bind(&GSTAdaptor::func2, &g, _1));
sigFunc1();//trigger the signal
sigFunc2(6);//trigger the signal
MattyTの例を新しいブースト(1.61など)でコンパイルすると、警告が表示されます
error: #warning "Boost.Signals is no longer being maintained and is now deprecated. Please switch to Boost.Signals2. To disable this warning message, define BOOST_SIGNALS_NO_DEPRECATION_WARNING."
したがって、警告を抑制するためにBOOST_SIGNALS_NO_DEPRECATION_WARNINGを定義するか、例を適宜変更することでboost.signal2に簡単に切り替えることができます。
#include <boost/signals2.hpp>
#include <boost/bind.hpp>
#include <iostream>
using namespace boost::signals2;
using namespace std;