tags:

views:

1082

answers:

7
+8  Q: 

Events in C++

I'm not sure how to look for this online... I think they might be called something different in C++

I want to have a simple event system, 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

I can do this pretty easily with a simple class -- but when i want to have an event that passes a different type or amount of arguments to the subscriber i have to write, and define an entirely new event class.. I figure there has to be some library, or maybe even something native in Visual C++ 2008 that will work something similar to this. It's basicly just an implementation of the Observer pattern, so it can't be too impossible to do in C++

This really makes me appreciate how nice it is in JavaScript not to have to worry about the arguments you are passing.

Tell me if this is a stupid question.

+4  A: 

The observer pattern from the GOF is pretty much what you want.

In the book, it has C++ code for this...

Also, as always, Boost has stuff you can make use of as well

Keith Nicholas
I'm looking into the book now. Boost calls them signals and slots I think.. and it seems they were doing a whole lot more than I needed. I may end up having to go more deeply into that though.
Robert
Besides the signals and slots in .NET (Visual C++) you have events and delegates. you can read more on them :)
milot
not really a C++ solution if you use .net
Keith Nicholas
Why was this voted -1? That's absurd, this is a valid (and good) solution.
mstrobl
I originally posted a one line reply, I'm picking I got downvoted then, but before I noticed that I thought, I didnt really give too much details. Still haven't really, what I've done in production code is created a templated based observer pattern like event system to handle different event types
Keith Nicholas
I keep reading about templated approaches, but I have no idea how to implement them.
Robert
I'd say here you'd use template< class PayLoad > class Event : public PayLoad {}. Of course, you could also just derive the other way round and spare the template. It's not so neat, though. :)
mstrobl
within the decleration of the fire() function you would just use public fire(PayLoad); ? and declare and event like event myEvent<float>?
Robert
You would create different kinds of PayLoad classes and have them contain, for example, float foo. But I strongly suggest going for a derived class rather than a templated approach for your needs. Define a Event-class and then define a class FooEvent : public Event { float foo; } Use references!
mstrobl
A: 

As I know from C# delegates, a delegate and a method must share the same signature, so if you have some delegate that will take a string and return an int, the method must be the same.

for example Click delegate and event:

public void delegate EventHandler(object sender, EventArgs e);

public event EventHandler OnClick();

and the method will be:

private void button1_Click(object sender, EventArgs e)
{
   // implementation
}

so as you can see the delegate and the method have the same signature, you cannot pass the KeyPressArgs to the Click event.

You can register an Click handler like this in C# (you can read more about this for VC++):

button1.Click += new EventHandler(button1_Click);

P.S it is not a stupid question, I gave you my vote for this question :)

milot
How would you connect button1_Click to the onClick event?
Robert
I edited the post to be more readable code, read from there.
milot
P.S you have the same logic with signals and slots. You can read the concept here: http://doc.trolltech.com/3.3/signalsandslots.html but it is for Qt toolkit but you can see how the concept works.
milot
+12  A: 

Take a look at the boost signal library. Combined with the function and bind libraries, you can do exactly what you are looking for.

Jere.Jones
+6  A: 

I use sigslot for exactly this purpose.

Jim Buck
I'm glad you reminded me of this... I didn't understand what signals/slots were when I came across it (still thinking events/subscribers)
Robert
This is exactly what I was looking for. stackoverflow is amazing.
Robert
A: 

There is a native Visual C++ event system. It's mostly for COM, but it has native C++ support too.

From 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);
}
Eclipse
A: 

I use libsigc++. It's native for gtkmm.

A: 

Hi, I want to use the sigslot library in my VC++ 2008 project. Does anybody know which praeprocessor commands I have to set? Currently I cannot include the lib ...

Here's my error log:

1>d:\michel\masterthesis\sources\test\test\sigslot.h(419) : warning C4346: 'std::set*>::const_iterator': Abhängiger Name ist kein Typ 1> Präfix mit 'typename' zum Angeben eines Typs 1> d:\michel\masterthesis\sources\test\test\sigslot.h(476): Siehe Verweis auf die Instanziierung der gerade kompilierten Klassen-template "sigslot::has_slots". 1>d:\michel\masterthesis\sources\test\test\sigslot.h(419) : error C2146: Syntaxfehler: Fehlendes ';' vor Bezeichner 'const_iterator' 1>d:\michel\masterthesis\sources\test\test\sigslot.h(419) : error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt. 1>Das Buildprotokoll wurde unter "file://d:\michel\masterthesis\sources\test\test\Debug\BuildLog.htm" gespeichert. 1>TrafficEvaluator - 2 Fehler, 1 Warnung(en) ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

Br, Markus

If you're expecting an answer, you'll have to start your own question.
Eclipse