用惯了其他语言的 try…catch…finally 结构,难免会对 C++ 的 try…catch 发生误解。
在其它语言里, try … catch 是无所不能的,所有你有本事整出来的异常都能被捕获,唯一让人头疼的是有些异常发生了,你不知道异常的类型,难于针对性地编写异常处理程序。
拥有其他语言编程习惯的人,如果换用 C++ ,满怀信心地用 try…catch 包裹了全部的工作代码,却失望地发现他连被零除、访问违例这样的异常都捕捉不到,发生异常时,程序该崩溃崩溃、该闪退闪退,精巧的异常处理逻辑毫无机会运行。不得不让人反思,这个 C++ 怎么了?
如果你这样问,答案就是,C++ 不是你想象的那个 C++,在其他语言里得心应手的编程技巧,在 C++ 里却无用武之地,因为 C++ 不是通常意义上的高级语言。
C++ 起源于 C,是 C 的扩充版本。C 从来不被真正的高手称为高级语言,业界公认他是中低级语言,C++ 自然受其连累,当不成正真的高级语言。C++ 语言是无所不能的工具,是一切的基础,用 C\C++ 可以写出所有别的高级语言,别的语言却没法写出 C\C++,就算你执着到变态,硬是用 VB 写出一个 C++ 编译器,执行效率也是差上几个数量级的。
事实上 C++ 和其他高级语言的差别,就等于是钢筋水泥手脚架和毛坯房的差别。
用其他高级语言编程,相当于你在装修毛坯房。如果在 C++ 里你想像别人一样装修毛坯房,你就得先建一个毛坯房出来才行。
错误捕捉机制就像水电气一样是毛坯房的基本要求,但不是手脚架的要求。所以 C++ 的标准规定 try…catch 只能捕捉用户代码 throw 出来的异常就是再自然不过的事情了。
微软公司就是喜欢做给脚手架也通水通电通气这样的事,他们给 VC 增加了一个 __try…__except 机制让用户可以捕捉Windows系统基础异常,
try{a= 1/0;}catch(…){这里的代码不会被执行();}
__try{a= 1/0;}__except(1){这里的代码会被执行();}
你也可以通过编译时添加 \EHa 选项,并在每个线程起始处调用 _set_se_translator 函数来把SEH异常转换为C++异常来让 try…catch 捕捉到Windows系统基础异常,
#include <exception>
_set_se_translator([](UINT nExceptionCode, PEXCEPTION_POINTERS pstExcptionInfor)->void __cdecl { throw nExceptionCode; });
try{a= 1/0;}catch(…){这里的代码可以被执行了();}
这样做之前你得明白,这是微软特色,之后你的代码失去了通用性变成了微软专属代码,只能被 VC 编译,换一种编译器都不可能编译通过。