Reputation: 481
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
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
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
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