c++ - 为什么在从 win32 计时器回调中抛出时不调用我的析构函数?

标签 c++ winapi exception

我刚问了this question .简而言之,当您从 win32 计时器回调中抛出异常时,异常似乎不会消失。它似乎在某处由 Windows 暗中处理。

好吧,那是个问题。问题的另一面是当抛出这个异常时,析构函数似乎没有被调用。在下面的代码中,对于 CFoo 的 std::vector,只有在 GetFooVect 中的临时对象被析构和 rValue 被复制到 fooVect 时才会输出“~CFoo”。 fooVect 的内容不会被破坏。

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

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 的破坏 vector 来重新创建它。出于某种原因,此处不会为 vector 中的事物调用析构函数。是什么赋予了?对此是否有合乎逻辑的解释,或者只是很奇怪,或者两者兼而有之?

最佳答案

您永远不应该允许异常传播到 C API 边界(如 SetTimer 回调)。 C 代码(和 Windows API 函数)对 C++ 语言异常一无所知。您不能依赖此类代码来传播您的异常。

您的回调应该在返回之前捕获所有 C++ 语言异常并适本地处理异常。如果您需要以某种方式将异常传达给您的应用程序的其余部分,您需要自己这样做。

(这里的其他人可能能够详细解释这种情况下发生的事情,但简短的回答是,在出现 C++ 语言异常的情况下,您不能依赖 C 代码来做正确的事情,因为它不知道 C++ 语言异常是什么。)

关于c++ - 为什么在从 win32 计时器回调中抛出时不调用我的析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8903811/

相关文章:

c++ - 双向链表 2 个值 C++

C++、WCHAR[] 到 std::cout 和比较

c++ - win32::WaitForSingleObject 期间 Windows 上的 Boost.Thread 断言/崩溃

java - 我应该使用什么返回语句才能使用针对非整数值引发异常的菜单?

java - 两次捕获异常类型

python - 在 except 中引发异常而不调用原始异常

使用 C++ 开发 iPhone 应用程序?

c++ - 'delete' 运算符在 C++ 动态内存分配(堆)的幕后实际上是如何工作的?

c++ - Boost 与 char 类型不同的共享内存对象问题

C++ : Incorrect File Size Calculation WinAPI