我想在使用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/

10-10 16:21