Da Maex
Da Maex

Reputation: 481

C++ Event Handling

i want to achieve an C# like Event Handling in Standard C++ (UNIX) like the following Code:

public class connection{

    public delegate void Message(object sender, string text);
    public event Message doMessage = null;

    //called from within a Thread or something alike
    private void MessageReceived(string Message){
        if (this.doMessage != null)
        {
            this.doMessage(this, Message);
        }
    }
}

public class Main{
    Connection con;

    public Main()
    {
        this.con = new Connection();
        this.con.doMessage += con_doMessage;
    }

    void con_doMessage(object sender, string message)
    {
        txtMain.Text = txtMain.Text + Environment.NewLine + message;
    }
}

I googled my fingertips bloody but all i found was Events firing, but not to an overlaying class like in my Example.

In fact, i'm new to Standard C++, maybe there is an easy way to get Data to the overlaying class, by firing it from within the class and i just didn't see it yet.

But yeah, as said, i have no clue and would be thankfull for some advice.

Upvotes: 2

Views: 5640

Answers (3)

Vittorio Romeo
Vittorio Romeo

Reputation: 93324

Use std::function as a callback:

void printSomething() { std::cout << "event!" << std::endl; }

int main() {
    std::function<void()> onEvent;
    onEvent = &printSomething;
    onEvent(); // prints "event!"
}

If you want C#-style delegates, use std::vector<std::function<...>>:

struct Delegate {
    std::vector<std::function<void()>> funcs;
    template<class T> Delegate& operator+=(T mFunc) { funcs.push_back(mFunc); return *this; }
    void operator()() { for(auto& f : funcs) f(); }
};

int main() {
    Delegate delegate;
    delegate += []{ std::cout << "hello, "; };
    delegate += []{ std::cout << "world!" << endl; };
    delegate(); // prints "hello, world!"
}

Or just copy my ssvu::Delegate class, available here.

Upvotes: 8

Konrad Rudolph
Konrad Rudolph

Reputation: 545865

Using std::function will probably be enough for almost all of your use-cases. In case you really need multiple event receivers, have a look at the multifunction (multicast delegate) proof of concept I wrote.

It allows you to write code that is syntactically similar to C#:

void f(int n) { cout << "f: " << n << "\n"; }

util::multifunction<void(int)> event;

event += f;
event += [](int n) { cout << "[]: " << n << "\n"; };

event(42);

Upvotes: 0

iavr
iavr

Reputation: 7637

This is relevant, or the same, with a very recent question. You can check my answer there. In short, a more complete/tested solution than building you own infrastructure may be Boost.Signals2.

Upvotes: 0

Related Questions