2008-10-26 12 views
19

Nie jestem pewien, jak wyglądają w tym Online ... Myślę, że można nazwać coś innego w C++Wydarzenia w C++

Chcę mieć prosty system zdarzeń, somthing jak

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 

Mogę to zrobić całkiem łatwo z prostą klasą - ale kiedy chcę mieć zdarzenie, które przekazuje inny typ lub ilość argumentów do subskrybenta muszę napisać i zdefiniować całkowicie nową klasę zdarzeń .. musi istnieć jakaś biblioteka, a może nawet coś natywnego w Visual C++ 2008, które będzie działało podobnie. Jest to po prostu implementacja wzorca Observer, więc nie jest to zbyt trudne w C++

To naprawdę sprawia, że ​​doceniam, jak przyjemnie jest w JavaScript, aby nie martwić się o przekazywane argumenty.

Powiedz, czy to jest głupie pytanie.

+3

Wcale nie głupi. –

Odpowiedz

10

Do tego celu używam sigslot.

+0

Cieszę się, że mi o tym przypomniałeś ... Nie wiedziałem, jakie sygnały/sloty były, kiedy je spotkałem (wciąż myślę o wydarzeniach/subskrybentach). – Robert

+3

Dokładnie tego szukałem. stackoverflow jest niesamowity. – Robert

8

Wzorzec obserwatora z GOF jest prawie taki, jak chcesz.

W książce ma kodu C++ dla tego ...

Ponadto, jak zawsze, doładowania ma rzeczy można wykorzystać także

+0

Teraz zajmuję się książką. Boost nazywa je sygnałami i gniazdami, które myślę ... i wygląda na to, że robią o wiele więcej, niż potrzebowałem. Być może jednak muszę w to jeszcze głębiej. – Robert

+0

Oprócz sygnałów i gniazd w .NET (Visual C++) masz zdarzenia i delegatów. możesz przeczytać więcej na ich temat :) – milot

+0

Naprawdę nie jest to rozwiązanie C++, jeśli używasz .net –

19

Spójrz na doładowania signal bibliotece. W połączeniu z bibliotekami function i bind możesz zrobić dokładnie to, czego szukasz.

6

Istnieje natywny język Visual C++ event system. Dotyczy to głównie COM, ale ma też natywną obsługę C++.

Od here:

[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); 
} 
2

używam libsigc++. Jest natywny dla gtkmm.

Prostym przykładem losely adaptacją 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(); 
} 

zapewnia również mechanizm połączenia członków funkcji określonych przedmiotów do sygnałów za pomocą sigc :: mem_fun zamiast sigc :: ptr_fun:

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

To wszystko zapewnia wszystko, co jest możliwe dzięki sygnałom GLib.