我想用C ++编写Windows编程中的C#事件驱动编程。
我想以这种方式实现这一目标:
活动类:
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"); }
};
这是一个实例:
EventArgs类的定义和窗口类:
class EventArgs{ };
class Win32Window
{
public:
// event definition
Event<Win32Window, EventArgs> Loaded;
// ctor
Win32Window(){
// ...
// trigger the Loaded event
Loaded(this, EventArgs());
}
// ...
};
事件处理函数的定义:
void Window_Loaded(Win32Window *sender, EventArgs e){
MessageBox(NULL, "Window_Loaded", "xx", 0);
}
主要功能:
Win32Window wnd;
//add the event handler function
wnd.Loaded += Window_Loaded;
它可以工作但是当窗口关闭时,list.clear()
中出现了运行时错误!
这是例外的snapshot:
答案 0 :(得分:1)
我认为,这正是std::function
旨在帮助解决的问题。为初学者尝试这样的事情:
#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);
}
请注意,此方法不仅可以将常规函数用作事件处理程序,还可以使用lambdas(如演示)以及函数对象。