我想在使用C ++的Windows编程中模拟C#事件驱动的编程。
我想以这种方式实现这一目标:
使用列表容器保存函数指针
覆盖+ =运算符,使Event类可以在其中添加函数
这样event + = handlerFuncName
覆盖()运算符,因此我们可以在列表中调用该函数
活动类别:
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类和window类的定义:
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异常:
最佳答案
我认为,这正是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);
}
请注意,此方法不仅使您可以将常规函数用作事件处理程序,而且还可以使用lambda(如所示)以及函数对象。
关于c++ - 调用list.clear()时发生运行时错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20612221/