yangyang12138

导航

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,调用就是发生了一种错误,调用者做相应的处理即可。

posted on 2016-11-18 14:33  杨杨09265  阅读(88)  评论(0)    收藏  举报