C++的异常处理
先来说说异常处理,异常处理就是发生了程序员预知以内,但是程序无法处理的错误,如函数:
void fun(double a) { if(a==0) throw a; double k = 100; k = k/a; }
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { try { fun(); } catch(int x) { cout<<"0不能作为此函数的参数"<<endl; } return 0; }
由于a=0时,k/a就会发生除0错误,所以我们在第一步 判断 a==0 如果成立我们必须以某种方式通知调用者,这种调用方式是错误的,让调用者处理这样异常调用,使程序不至于崩溃,调用时使用了 try{}catch{},由于fun中抛出了异常,
catch捕获此异常,在catch函数里可以做异常恢复。catch我们都知道必须和try同时使用,否则没任何意义,但是大家都忽略了在背后默默工作的throw,若果没有throw try-catch 没有任何意义。也就是说必须在try里调用了throw的时候,catch中
才能捕获到异常。用过ado的人都知道,我们大量用到了try catch,但是从来没有throw过任何东西,不过在你调用的ado函数里throw啦。也就是 try throw catch 永远是配套使用的。
接下来我们来谈谈throw的工作原理,断点进入反汇编查看,在throw的位置其实是调用了一个函数:_CxxThrowException
00975265 mov eax,dword ptr [a] 00975268 mov dword ptr [ebp-0D4h],eax 0097526E push 980134h 00975273 lea ecx,[ebp-0D4h] 00975279 push ecx 0097527A call __CxxThrowException@8 (097128Ah)
具体细节就不说了,这个函数的源码大家也可以看到,在throw.cpp中,感兴趣的看以自己去看,这个函数里获取throw传的参数,封装了一些信息之后,进入另一个函数,这个函数才是异常抛出的真正地方,这个函数没有源码,只能看反汇编,这里寻找调用者catch
语句函数,并调用,如果我们没有catch此类型的异常,调用时就会发生,访问非法而使程序崩溃。
从上述可以看出throw异常并chath此异常到程序恢复运行,程序其实一直都在正确运行,只不过是一个函数调用而已。所以如果发生错误(数组越界,访问保护区,除0,内存不足,尝试回收栈内存等),catch绝对是爱莫能助啦。
这个其实非常类似于C语言是的调用方式,
int funC(double a) { if(a==0) return 1; double k = 100; k = k/a; return 0; }
返回结果只要不是0,调用就是发生了一种错误,调用者做相应的处理即可。
浙公网安备 33010602011771号