c++异常处理

                                                               异常处理
      C++语言本身或标准程序库所抛出的所有异常,都派生自基类exception。这是其他数个标准异常类别的基类,它们共同构成一个类体系:

传统错误处理办法
1. 终止程序。(如段错误等)
2. 返回错误码。
3. 返回合法值,让程序处于某种⾮法的状态。(误导人,不可用)
4. 调一个预先设置的出现错误时调⽤的函数。(回调函数)
5.使用abort()或exit()暴力终止程序
6.使用goto语句
7. set jmp()和long jmp()组合(set jump必须先调用,在异常位置通过调用long jmp以恢复先前被保存的程序执行点,否则将导致不可预测的结果,甚至程序崩溃。在调用setjmp的函数返回之前调动longjmp,否则结果不可预料)
异常对象的类型与catch说明符的类型必须完全匹配。只有以下三种情况例除外
1. 允许从const对象到const的转换。
2. 允许从派类型到基类类型的转换。
3. 将数组转换为指向数组类型的指针,将函数转换为指向函数类型的指针。
先简单的看一个例子:
double fun(int x,int y)
{
        if (y==0)
        {
             throw 1;
        }
        return x/y;
}
int main()
{  
     try
     {   
        cout<<"4/4="<<fun(4,4)<<endl;
        cout<<"4/0="<<fun(4,0)<<endl;
     }
     catch (...)
     {
          cout<<"y!=0"<<endl;
     }  
          return 0;
}


   
这里catch后圆括号中的...指的是捕获所有异常。
        抛出异常后会释放局部存储对象,所以被抛出的对象也就还给系统了,throw表达式会初始化这个抛出特殊的异常对象副本(匿名对象),异常对象由编译管理,异常对象在传给对应的catch处理之后撤销。栈展开抛出异常的时候,将暂停当前函数的执行,才开始查找对应的匹配catch语句。先检查throw是否在try块内部,如果是再查找匹配的catch语句。 如果有匹配的,则处理。没有则退出当前函数栈,继续在调函数的栈中进行查找不断重复上述过程。若到达main函数的栈,依旧没有匹配的,则终止程序。上述这个沿着调用链查找匹配的catch句的过程称为栈展开。找到匹配的catch语句并处理以后,会继续沿着catch语句继续执行。
       在栈展开的时候,会退出某个函数,释放当前内存并撤销局部对象,这时会调用对象的析构函数,如果析构函数抛出异常,将会调用标准库terminate函数,强制整个程序非正常退出。所以析构函数应该从不抛出异常。
       异常是通过抛出对象引发的,该对象的类型决定了应该激活哪个处理代码。
       在查找匹配的catch期间,找到的catch不必是与异常最匹配的那个catch,相反,将选中第一个找到的可以处理该异常的catch。因此,在catch子句列表中,最特殊的catch必须最先出现,否则没有执行的机会。
实例如下:
int  FunTest1()
{
     int error1=1;
     throw error1;
}
char FunTest2()
{   
     char error2='2';
     throw error2;
}
int main()
{
      try
      {
     FunTest1();
      FunTest2();
      }
      catch (int &error1)
      {
            cout<<"int "<<endl;
      }
      catch (char &error1)
      {
           cout<<"char"<<endl;
      }
     return 0;
}

         进入catch的时候,用异常对象初始化catch的形参。因为基类的异常说明符可以捕获派生类的异常对象。如果异常对象是引用,则可以使用多态,调用基类的virtual将执行派生类的覆盖的函数。若catch的异常说明符是对象,则将派生类对象分割为它的基类对象。
异常捕获的匹配规则
        异常的重新抛出原因有可能单个的catch不能完全处理一个异常,在进行一些校正处理以后,希望再交给更外层的调用链函数来处理,catch则可以通过重新抛出将异常传递给更上层的函数进行处理。
void func1(int i) 
    { 
        if(i<0) 
            throw -1; 
        if(i>100) 
            throw -2;    
    }  
    void func2()
    { 
        try 
        {     int m=0;
            func1(199); 
        } 
    catch (int i) 
        { 
              cout<<"Error Code:"<<i<<endl;
        } 
    } 
void  func3()
{
    try
    {
          func2();
    }
    catch (int m)
    {
          cout<<"Error Code:"<<m<<endl; 
    } 
}
int main()
{   
          func2();
          func3();
   system("pause");
   return 0;
}

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值