我刚问了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/