program tip

Boost :: Signals for C ++ Eventing을 사용한 완전한 예제

radiobox 2020. 12. 30. 08:00
반응형

Boost :: Signals for C ++ Eventing을 사용한 완전한 예제


나는 이것을 다루는 boost.org의 튜토리얼을 알고있다 : Boost.org Signals Tutorial , 그러나 예제는 완전하지 않고 다소 단순화되어있다. 여기에있는 예제는 포함 파일을 표시하지 않으며 코드의 일부 섹션은 약간 모호합니다.

필요한 것은 다음과 같습니다.
ClassA가 여러 이벤트 / 신호를 발생시킵니다.
ClassB가 해당 이벤트를 구독합니다 (여러 클래스가 구독 할 수 있음).

내 프로젝트에는 해당 메시지를 처리하고 UI (wxFrames)에 알리는 비즈니스 클래스에 이벤트를 발생시키는 하위 수준 메시지 처리기 클래스가 있습니다. 이 모든 것이 어떻게 연결되는지 (어떤 순서, 누가 누구에게 전화하는지 등) 알아야합니다.


아래 코드는 요청한 작업의 최소 작업 예입니다. ClassA두 개의 신호를 방출합니다. SigA매개 변수를 전송 (수락) SigB하고 int. 각 함수가 호출 될 때 ClassB출력되는 두 개의 함수 cout가 있습니다. 이 예에는 ClassA( a) 인스턴스가 하나 있고 ClassB( bb2) 인스턴스가 두 개 있습니다. main신호를 연결하고 발사하는 데 사용됩니다. 있다는 지적이의 가치 ClassAClassB서로 아무것도 몰라 (그들이하지 않는 즉 , 컴파일시 바인딩 ).

#include <boost/signal.hpp>
#include <boost/bind.hpp>
#include <iostream>

using namespace boost;
using namespace std;

struct ClassA
{
    signal<void ()>    SigA;
    signal<void (int)> SigB;
};

struct ClassB
{
    void PrintFoo()      { cout << "Foo" << endl; }
    void PrintInt(int i) { cout << "Bar: " << i << endl; }
};

int main()
{
    ClassA a;
    ClassB b, b2;

    a.SigA.connect(bind(&ClassB::PrintFoo, &b));
    a.SigB.connect(bind(&ClassB::PrintInt, &b,  _1));
    a.SigB.connect(bind(&ClassB::PrintInt, &b2, _1));

    a.SigA();
    a.SigB(4);
}

출력 :


바 : 4
바 : 4

간결함을 위해 프로덕션 코드에서 일반적으로 사용하지 않는 몇 가지 바로 가기를 사용했습니다 (특히 액세스 제어가 느슨하고 일반적으로 KeithB의 예와 같은 기능 뒤에 신호 등록을 '숨기기').

대부분의 어려움 boost::signal은 사용에 익숙해지는 것 같습니다 boost::bind. 그것은 이다 처음에는 비트 압도적 인! 교묘의 예를 들어, 당신은 또한 사용할 수있는 bind훅을 ClassA::SigA함께 ClassB::PrintInt하지만도 SigA않습니다 하지 을 방출 int:

a.SigA.connect(bind(&ClassB::PrintInt, &b, 10));

도움이 되었기를 바랍니다.


다음은 코드베이스의 예입니다. 단순화 되었기 때문에 컴파일 될 것이라고 보장하지는 않지만 가깝습니다. Sublocation은 클래스 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;
};

하위 위치 .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;
};

슬롯 1.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는 자체 신호 및 슬롯 구현을 제공합니다. 다음은 구현의 몇 가지 예입니다.

Signal and Slot connection for namespace

Consider a namespace called GStreamer

 namespace GStremer
 {
  void init()
  {
  ....
  }
 }

Here is how to create and trigger the signal

 #include<boost/signal.hpp>

 ...

 boost::signal<void ()> sigInit;
 sigInit.connect(GStreamer::init);
 sigInit(); //trigger the signal

Signal and Slot connection for a Class

Consider a Class called GSTAdaptor with function called func1 and func2 with following signature

void GSTAdaptor::func1()
 {
 ...
 }

 void GSTAdaptor::func2(int x)
 {
 ...
 }

Here is how to create and trigger the signal

#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

When compiling MattyT's example with newer boost (f.e. 1.61) then it gives a warning

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." 

So either you define BOOST_SIGNALS_NO_DEPRECATION_WARNING to suppress the warning or you could easily switch to boost.signal2 by changing the example accordingly:

#include <boost/signals2.hpp>
#include <boost/bind.hpp>
#include <iostream>

using namespace boost::signals2;
using namespace std;

ReferenceURL : https://stackoverflow.com/questions/768351/complete-example-using-boostsignals-for-c-eventing

반응형