为什么从Win32计时器回调中抛出时,我的析构函数为什么不被调用? [英] Why aren't my destructors called when throwing from a win32 timer callback?

查看:31
本文介绍了为什么从Win32计时器回调中抛出时,我的析构函数为什么不被调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚问过这个问题.简而言之,当您从Win32计时器回调中引发时,该异常似乎不会发生.Windows似乎在秘密地处理了它.

I just asked this question. In short, when you throw from a win32 timer callback, the exception doesn't appear to go anywhere. It seems to be surreptitiously handled by Windows somewhere.

好的,那就是一个问题.问题的另一面是,抛出此异常时似乎不会调用析构函数.在以下代码中,对于CFoo的 std :: vector ,唯一的输出〜CFoo"的时间是销毁GetFooVect中的临时对象以及将rValue复制到fooVect时.fooVect的内容不会被破坏.

OK well thats a problem. The OTHER side of the problem is that destructors don't seem to be getting called when this exception IS thrown. In the following code, for the std::vector of CFoo, the only time "~CFoo" is output is when the temporaries in GetFooVect are destructed and when the rValue is copied to fooVect. The contents of fooVect are NOT destructed.

这是我最糟糕的噩梦.我大量使用RAII.我非常依赖我的析构函数来进行适当的清理.

This is my worst nightmare. I use RAII pretty heavily. I lean pretty heavily on my destructors to cleanup appropriately.

class CFoo
{
public:
    ~CFoo() {printf(__FUNCTION__ "\n");}
};

std::vector< CFoo > GetFooVect()
{
    std::vector< CFoo > rValue;
    rValue.push_back(CFoo());
    rValue.push_back(CFoo());
    rValue.push_back(CFoo());
    return rValue;
}

VOID CALLBACK Timer(HWND hwnd,
    UINT uMsg,
    UINT_PTR idEvent,
    DWORD dwTime)
{
    // My destructors aren't called?
    std::vector< CFoo> fooVect = GetFooVect();

    // I'm destroyed
    CFoo aFoo;

    throw FooExcept();
    printf("Also Here\n");
}

我试图通过简单地抛出/捕获C ++异常(即删除win32计时器回调变量)和CFoo的破坏向量来重新创建它.由于某种原因,这里没有针对向量中的事物调用析构函数.是什么赋予了?对此是否有合乎逻辑的解释,或者只是很奇怪,还是两者都有?

I've tried recreating this by simply throwing/catching C++ exceptions (ie removing the win32 timer callback variable) and the vector of CFoo's destructs just fine. For some reason, destructors are NOT being called here for things in vectors. What gives? Is there a logical explanation for this, or is it just weird, or both?

推荐答案

永远不要让异常在C API边界上传播(例如SetTimer回调).C代码(和Windows API函数)对C ++语言异常一无所知.您不能依靠此类代码来传播异常.

You should never, ever allow am exception to propagate across a C API boundary (like the SetTimer callback). C code (and the Windows API functions) know nothing about C++ language exceptions. You cannot rely on such code to propagate your exceptions.

您的回调应在返回之前捕获所有C ++语言异常,并适当地处理这些异常.如果您需要以某种方式将异常与应用程序的其余部分进行通信,则需要自己进行通信.

Your callback should catch all C++ language exceptions before returning and handle the exceptions appropriately. If you need to somehow communicate the exceptions to the rest of your application, you need to do so yourself.

(这里的其他人也许可以详细解释这种情况下发生的事情,但是简短的答案是,在存在C ++语言异常的情况下,您不能依靠C代码来做正确的事情,因为它不知道什么是C ++语言异常.)

(Someone else here may be able to explain in detail what is happening in this case, but the short answer is that you can't rely on C code to do the right thing in the presence of a C++ language exception, because it has no idea what a C++ language exception is.)

这篇关于为什么从Win32计时器回调中抛出时,我的析构函数为什么不被调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆