【c++】异常处理

【c++】异常处理

 1. 什么是异常?

 2. 异常的分类

 3. 异常处理

4. 异常的重新抛出----嵌套结构

参考:《c++从入门到精通》  人民邮电出版社

    经过前面几章的学习,我们已经掌握了基本的程序编写,但是这些程序还比较脆弱,发生意料之外的问题怎么办呢?

    是束手无策放任应用程序崩溃呢,还是遇到意外时让程序安全退出呢,还是选择更好的解决办法?比如:针对不同的异常问题选择不同的解决方法。

1. 什么是异常?

    异常(exception),就是程序在运行过程中,由于使用环境的变化以及用户的操作而产生的错误。

    所有的程序都有bug,程序规模越大,bug越多。为了尽可能地减少正式发布软件中的bug,一个软件在经历了demo版本后,会经历Alpha版本(内部测试版),然后是beta版本(外部测试版),最后才发布release版本(即 正式版本)。之后还会发布补丁包和升级版本。这就说明了所有的程序都有潜在或未发现的bug。

2. 异常的分类

    按异常发生的时刻,可将异常分类为两种:

    (1)   语法错误:程序中执行了错误的语句或者函数类等,导致编译程序无法进行。

    (2) 运行时发生的错误:这一般与算法、逻辑有关。常见的有:文件打开失败、数组下标溢出、系统内存不足等。

3. 异常处理

    异常处理是对程序运行过程中突如其来的错误的处理。使用异常处理机制,可以使程序更加安全、可靠。

    异常处理机制的本质是:程序处理流程的转移,适度的、恰当的转移会起到很好的作用。

    (1) 异常处理语句块

    异常处理语句块有3个:try\catch\throw

    Try语句块:用来框定异常。要处理异常,先框定可能产生异常的语句块。

    Catch语句块:定义处理异常。将出现异常后的处理语句放在catch块中,以便当异常被抛出后,进行类型匹配,捕获异常并处理。

    Throw语句块:抛出异常。在可能产生异常的语句中进行错误检查,如果有错误,就抛出异常。

    (2) 使用try-throw-catch处理异常

    使用try-throw-catch处理异常 ,格式为:

           

【异常处理实例】

代码:

//异常处理.cpp

#include<iostream>
#include<string>
using namespace std;

class myClass{} ;
struct myStruct{};

void fun(int i)
{
try{     // 可能出现异常的语句块,根据i值的不同,抛出不同的异常
    if(i==1)
    {
        throw 1 ;  //抛出整型异常
    }
    else if(i==2)
    {
        throw  1.2 ;  //抛出double异常
    }
    else if(i==3)
    {
        throw myClass() ;  //抛出 类 异常
    }
     else if(i==4)
    {
        throw myStruct() ;  //抛出 结构体 异常
    }
}

    catch(int i)    //捕获整型异常
    {
        cout<<"catch is int\n";
    }
     catch(double a)    //捕获double异常
    {
        cout<<"catch is double\n";

    }
     catch(myClass)  //捕获  类  异常
    {
        cout<<"catch is myClass\n";

    }
     catch(...)  //捕获 结构体 异常
    {
        cout<<"catch is myStruct\n";

    }

}

int main(int argc,char *argv[])
{
        try
        {
            fun(1);
            fun(2);
            fun(3);
            fun(4);

        }
        catch(int i)
        {
            cout<<"main() error!"<<endl;
        }

        cout<<"main() is OK!"<<endl;
    return 0;
}

运行结果:

    经分析可发现,catch会根据throw抛出的不同类型,来进行捕获。

4. 异常的重新抛出----嵌套结构

    在c++异常处理的嵌套结构中,规则是:外层的throw抛出的异常使用外层的catch来捕获,内层的throw抛出的异常使用内层的catch来捕获。

    如果我们希望内层抛出的异常由外层的catch来捕获,这就需要使用异常的层层传递手段了,这要用到throw语句不带表达式的形式。 

throw语句(不带表达式),内嵌在catch内,意味着当前catch块在入口中捕获的类型信息,throw接力地将此类型信息抛出到上层的相应类型入口的catch捕获器,特定异常就从内层传到了外层需要的地方。

【编程实例】实现异常嵌套

代码:

//异常嵌套处理.cpp

#include<iostream>
#include<string>
using namespace std;

void funa(int i)
{
try{     // 可能出现异常的语句块,根据i值的不同,抛出不同的异常
    if(i==1)
    {
        throw 1 ;  //抛出整型异常
    }
    else if(i==2)
    {
        throw 1.2;  //抛出double异常
    }

}

    catch(int i)    //捕获整型异常
    {
         cout<<"funa 抛出int异常\n";
         throw;
    }
     catch(double a)    //捕获double异常
    {
        cout<<"funa 抛出double异常\n";
        throw;

    }
    cout<<"funa 正常运行\n";


}

void funb(int i)
{
    try
    {     // 可能出现异常的语句块,根据i值的不同,抛出不同的异常
        funa(i);
    }

    catch(int i)    //捕获整型异常
    {
        cout<<"funb 重新抛出int异常\n";
        throw;
    }
     catch(double a)    //捕获字符串异常
    {
        cout<<"funb 重新抛出double异常\n";
        throw;
    }

}

void func(int i)
{
    try
    {     // 可能出现异常的语句块,根据i值的不同,抛出不同的异常
        funb(i);
    }

    catch(int i)    //捕获整型异常
    {
        cout<<"func 最终解决int异常\n";
    }
     catch(double a)    //捕获字符串异常
    {
        cout<<"func 最终解决double异常\n";

    }

}


int main(int argc,char *argv[])
{
    int a=1;
    int b=2;
        try
        {
            func(a);
            func(b);

        }
        catch(int i)
        {
            cout<<"main() error!"<<endl;
        }

        cout<<"main() is OK!"<<endl;
    return 0;
}

运行结果:

经分析,可发现,调用func时,需调用funb,调用funb需调用funa。这样就构成了嵌套结构,同时利用catch和throw也实现了不同层级的异常的传递和处理。

 -------------------------------------------         END      -------------------------------------

猜你喜欢

转载自blog.csdn.net/u012679707/article/details/80307595