Reputation: 39
I want to simulate the C# Event-Driven Programming in Windows Programming with C++.
I want to accomplish that in this way :
Event class:
template<class Sender_Type, class Args_Type>
class Event{
private:
typedef void(*HFUN)(Sender_Type *, Args_Type);
list<HFUN> handlers;
public:
void operator +=(HFUN handler){
handlers.push_back(handler);
}
void operator ()(Sender_Type *sender, Args_Type e){
for (list<HFUN>::iterator it = handlers.begin(); it != handlers.end(); it++)
(*it)(sender, e);
}
~Event(){ printf("Release..\n"); }
};
and here is a instance :
the definition of EventArgs class and the window class:
class EventArgs{ };
class Win32Window
{
public:
// event definition
Event<Win32Window, EventArgs> Loaded;
// ctor
Win32Window(){
// ...
// trigger the Loaded event
Loaded(this, EventArgs());
}
// ...
};
the definition of the event handler function:
void Window_Loaded(Win32Window *sender, EventArgs e){
MessageBox(NULL, "Window_Loaded", "xx", 0);
}
main function:
Win32Window wnd;
//add the event handler function
wnd.Loaded += Window_Loaded;
It works but when the window was closing, there was runtime error in list.clear()
!
Here is a snapshot of exception:
Upvotes: 0
Views: 198
Reputation: 16864
This is, I think, precisely the kind of problem that std::function
was intended to help with. Try something like this for starters:
#include <functional>
#include <iostream>
#include <vector>
template <typename Sender, typename... Args>
class Event
{
using FuncType = std::function<void(Sender&, Args...)>;
std::vector<FuncType> vec;
public:
Event& operator+=(FuncType f) {
vec.push_back(f);
return *this;
}
void operator()(Sender& s, Args... a) {
for (auto& f : vec) {
f(s, a...);
}
}
};
struct Window
{
Event<Window, int, int> resized;
void resize(int width, int height) {
// blah blah
resized(*this, width, height);
}
};
int main()
{
Window w;
w.resized += [](Window&, int w, int h) {
std::cout << "Window resized to " << w << " by " << h << std::endl;
};
w.resize(800, 600);
}
Note that this method allows you to not only use regular functions as event handers, but also lambdas (as demonstrated), and also function objects.
Upvotes: 1