Dou*_* T. 1 c++ winapi exception
我刚问了这个问题.简而言之,当你从win32计时器回调中抛出时,异常似乎无处可去.它似乎是由Windows在某处偷偷摸摸地处理的.
好吧,这是一个问题.问题的另一方面是抛出此异常时似乎没有调用析构函数.在下面的代码中,对于std::vectorCFoo,输出"~CFoo"的唯一时间是当GetFooVect中的临时值被破坏以及rValue被复制到fooVect时.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");
}
Run Code Online (Sandbox Code Playgroud)
我尝试通过简单地抛出/捕获C++异常(即删除win32计时器回调变量)来重新创建这个,并且CFoo的向量可以很好地破坏.出于某种原因,析构函数不会在这里被称为向量中的东西.是什么赋予了?对此有合理的解释,还是只是奇怪,或两者兼而有之?
您永远不应该允许异常传播跨越C API边界(如SetTimer回调).C代码(和Windows API函数)对C++语言异常一无所知.您不能依赖此类代码来传播您的异常.
您的回调应该在返回之前捕获所有C++语言异常并适当地处理异常.如果您需要以某种方式将异常传达给应用程序的其余部分,则需要自己执行此操作.
(这里的其他人可能能够详细解释在这种情况下发生了什么,但简短的回答是你不能依赖C代码在存在C++语言异常的情况下做正确的事情,因为它没有想法是什么C++语言异常.)