Events in C++

Events in C++

本文关键字:C++ in Events      更新时间:2023-10-16

我不知道如何在网上寻找这个...我认为它们可能会被称为不同的东西C++

我想要一个简单的事件系统,比如

event myCustomEvent;
myCustomEvent.subscribe( void myHandler(string) );
myCustomEvent.fire("a custom argument");
// myHandler prints out the string passed in the first argument

event myNewCustomEvent;
myNewCustomEvent.subscribe( void myNewHandler(int) );
myNewCustomEvent.fire(10);
// myHandler prints 10

我可以用一个简单的类很容易做到这一点 - 但是当我想让一个事件将不同类型或数量的参数传递给订阅者时,我必须编写并定义一个全新的事件类。我认为必须有一些库,甚至是Visual C++ 2008中的原生库,可以与此类似。它基本上只是观察者模式的实现,所以在C++中不可能做到

这真的让我体会到JavaScript中不必担心你传递的参数是多么美好。

告诉我这是否是一个愚蠢的问题。

查看升压信号库。 结合函数和绑定库,您可以完全执行所需的操作。

我使用sigslot正是为此目的。

来自 GOF 的观察者模式几乎是你想要的。

在书中,它为此C++代码...

此外,与往常一样,Boost也有您可以使用的东西

有一个本机的视觉C++事件系统。 它主要用于 COM,但它也有本机C++支持。

从这里:

[event_source(native)]
class CSource {
public:
   __event void MyEvent(int nValue);
};
[event_receiver(native)]
class CReceiver {
public:
   void MyHandler1(int nValue) {
      printf_s("MyHandler1 was called with value %d.n", nValue);
   }
   void MyHandler2(int nValue) {
      printf_s("MyHandler2 was called with value %d.n", nValue);
   }
   void hookEvent(CSource* pSource) {
      __hook(&CSource::MyEvent, pSource, &CReceiver::MyHandler1);
      __hook(&CSource::MyEvent, pSource, &CReceiver::MyHandler2);
   }
   void unhookEvent(CSource* pSource) {
      __unhook(&CSource::MyEvent, pSource, &CReceiver::MyHandler1);
      __unhook(&CSource::MyEvent, pSource, &CReceiver::MyHandler2);
   }
};
int main() {
   CSource source;
   CReceiver receiver;
   receiver.hookEvent(&source);
   __raise source.MyEvent(123);
   receiver.unhookEvent(&source);
}

我使用libsigc++。它是 gtkmm 的原生版本。

一个简单的例子,从教程中改编而来:

#include <iostream>
#include <sigc++/sigc++.h>
using namespace std;
class AlienDetector {
public:
        void run ();
        sigc::signal<void> signal_detected;
};
void warn_people () {
        cout << "There are aliens in the carpark!" << endl;
}
void AlienDetector::run () {
        signal_detected.emit ();
}
int main () {
        AlienDetector mydetector;
        mydetector.signal_detected.connect (sigc::ptr_fun (warn_people));
        mydetector.run ();
}

它还提供了一种机制,使用 sigc::mem_fun 而不是 sigc::p tr_fun 将特定对象的成员函数连接到信号:

sigc::mem_fun (someobject, &SomeClass::some_method);

这几乎提供了GLib信号所能提供的任何可能。

这是我

在Arduino项目上使用的一个简单的C++委托实现。它依赖于智能指针,以便在附加事件处理程序时允许更简洁的语法。它只支持一个处理程序,但这可以通过实现一些事件委托容器来轻松扩展。

template<typename TSender, typename TArgument>
class EventDelegate {
private:
  struct Callable {
    virtual ~Callable() {}
    virtual void Call(TSender* sender, TArgument* argument) = 0;
  };
  template<typename TClass>
  struct CallableImpl : public Callable {
    TClass* _instance;
    void (TClass::*_method)(TSender*, TArgument*);
    CallableImpl(TClass* instance, void (TClass::*method)(TSender*, TArgument*))
      : _instance(instance), _method(method) {}
    void Call(TSender* sender, TArgument* argument) {
      (_instance->*_method)(sender, argument);
    }
  };
protected:
  RefCountedPtr<Callable> _callable; // smart pointer
public:
  template<typename TClass>
  EventDelegate(const TClass* instance, void (TClass::*method)(TSender* sender, TArgument* argument))
    : _callable(new CallableImpl<TClass>(instance, method)) {}
  EventDelegate()
    : _callable(0) {}
  ~EventDelegate() {
  }
  void operator()(TSender* sender, TArgument* argument) {
    if (_callable) {
      _callable->Call(sender, argument);
    }
  }
};

这是如何使用它

class Button {
public:
  typedef EventDelegate<Button, ButtonClickArgs> ClickEvent;
  ClickEvent OnClick;
protected:
  RaiseClick() {
    ButtonClickArgs args(...);
    OnClick(this, &args)
  }
};
class App {
public:
  App() {
    // Here the smart pointer ensures that the Callable isn't
    // destroyed when the Button::ClickEvent object on the stack 
    // goes out of scope
    g_button->OnClick = Button::ClickEvent(this, &App::ClickHandler)
  }
  ~App() {
    g_button->OnClick = Button::ClickEvent();
  }
protected:
  void ClickHandler(Button* button, ButtonClickArgs* args) {
    ...
  }
};