调用list.clear()时的运行时错误

时间:2013-12-16 13:32:42

标签: c++ windows list stl clear

我想用C ++编写Windows编程中的C#事件驱动编程。

我想以这种方式实现这一目标:

  1. 使用列表容器来保存函数指针
  2. 覆盖+ =运算符,使类Event可以添加函数 这样 event + = handlerFuncName
  3. 覆盖()运算符,因此我们可以调用列表中的函数
  4. 活动类:

    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

1 个答案:

答案 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(如演示)以及函数对象。