Ответ 1
Я использую sigslot именно для этой цели.
Я не уверен, как искать этот онлайн... Я думаю, что они могут быть названы чем-то другим в С++
Я хочу иметь простую систему событий, somthing like
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 С++ 2008, которое будет работать с чем-то похожим на это. Это, по сути, просто реализация шаблона Observer, поэтому его невозможно сделать в С++
Это действительно заставляет меня оценить, насколько хорошо в JavaScript не беспокоиться о аргументах, которые вы передаете.
Скажите, если это глупый вопрос.
Я использую sigslot именно для этой цели.
Взгляните на библиотеку boost signal. В сочетании с function и bind библиотеки, вы можете делать именно то, что ищете.
Шаблон наблюдателя от GOF в значительной степени зависит от того, что вы хотите.
В книге для этого есть код С++...
Кроме того, как всегда, у Boost есть вещи, которые вы можете использовать также
Существует среда Visual С++ система событий. Это в основном для COM, но у него есть встроенная поддержка С++.
Из здесь:
[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);
}
Я использую libsigС++. Он является родным для gtkmm.
Простой пример, адаптированный из tutorial:
#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:: ptr_fun:
sigc::mem_fun (someobject, &SomeClass::some_method);
Это в значительной степени обеспечивает все, что возможно с GLib-сигналами.