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

Posted

技术标签:

【中文标题】调用 list.clear() 时出现运行时错误【英文标题】:runtime error when the list.clear() was called 【发布时间】:2013-12-16 13:32:42 【问题描述】:

我想用 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 类和窗口类的定义:

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 的异常:

【问题讨论】:

看不到你的图片... 什么是 HFUN?您能否显示初始化和清除此列表的代码,事件处理程序代码的问题不是必需的。请尝试将其减少到SSCCE。 成员函数指针显然不是答案。尝试阅读 Functors。 typedef void(*HFUN)(Sender_Type *, Args_Type);我还没有调用 clear() 函数。我认为它是在列表发布时自动调用的。对列表(处理程序)的所有操作都显示在这些代码中,不再有任何操作。 使用std::function 肯定会让这更容易阅读......而且更安全 【参考方案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);

请注意,此方法不仅允许您使用常规函数作为事件处理程序,还可以使用 lambda(如演示)和函数对象。

【讨论】:

非常感谢。这对我很有帮助。

以上是关于调用 list.clear() 时出现运行时错误的主要内容,如果未能解决你的问题,请参考以下文章

尝试注销 django 时出现运行时错误

使用 torch.load 时出现运行时错误“存储大小错误:”

调用 API 函数时出现 ESP 错误?

运行 Oracle 调度程序时出现错误:ORA-20001:必须从应用程序会话中调用此过程

尝试调用方法 imagerotate 时出现 500 内部服务器错误

调用 SDL_SetVideoMode 时出现分段错误