C++的异常处理

异常,通常是指程序困难检测到的,运行是不正常的情况,例如被0除,数组越界访问等等。

异常处理的语法通常是

try
{
   throw()
}
catch()
{
}


关键字try以及它后的大括号中的内容我们称其为try块。简单的说,它包含的是可能会出错的地方(就是我们要检测的地方)。当我们检测到一个错误信息的时候,关键字throw就把这个错误抛出来(强呀:)),抛出来怎么办呢?抛哪去呢?我们的catch关键字就给我们解决掉了这个问题。catch通常用来接收throw抛出来的异常。请注意了,throw抛出来的类型要与catch接受的类型要匹配。就像把一个数字5只能附给一个int型的a一样(当然 int型的b也可以...耳后生风,似乎有砖飞来。。。)

下来,让我来学习一下异常处理的三种用法:

 

1:常见的异常处理

我们来看下下一段的代码:

#i nclude <iostream>

#i nclude <string>

#i nclude <math.h>

using namespace std;

 

class triangle  //定义一个三角形的类

{

    public :

    float a,b,c,d;  //三角形三边a,b,c,海伦公式常量d

    float s;          //三角形面积

    public:

    triangle()

    {}

    triangle(float a1,float b1,float c1)

    {

      a=a1;

      b=b1;

      c=c1;

    }

    void judgment()//判断是否是三角形

    {

        string yorn;

        if((a+b)<c ||(a+c)<b || (c+b)<a)//任意两边和小于第三边,就不是三角形

        {

            yorn="不是三角形";

            throw(yorn); 

        }        

        /*如果任意两边和小于第三边,我们就认为是一个异常(不是三角形,让我算什么呢??),

         * 用throw抛出。注意,我们定义了一个string形的变量 yorn(是或不是),并将其抛出

         * 。接受的时候也要用string类型来接收。下面就会看到~~*/

      

    }

    void dimension()//计算面积

    {

      d=(a+b+c)/2;        //海伦公式

      s=sqrt(d*(d-a)*(d-b)*(d-c));

    }

};

void main()

{

    triangle a(7,2,3);

    try

    {

        a.judgment();

        a.dimension();

        cout<<"三角形a的面积为: "<<a.s<<endl;

    }

    //接受了,接受了,请注意,我还是定义了一个 string形的来接受的。

    //那么我能不能定义一个int  或别的类型的呢?可以,

    //完全可以,只是接受不到罢了:)...又有砖飞来。。。*/

    catch (string &err)  

    {

        cout<<err<<endl;

    }

}

 

 

 

 

 

当然,c++也给提供了一个万能的接收器,

你也可以写成这样

catch(...)

{

    cout<<"错了伙计,你知道什么是三角形吗?"<<endl;

}

这里的catch(...)就是一个万能的接收器(别问我为什么,c++规定就是这样写的,就像你不要问我为什么要写这篇文章一样,夜深了,我还在写着...写着...对不起,跑远了,拉回来.)

 

 

 

 

 

万能接收器也可以和我写的这个catch放一起用,比如你又可以写成:

try

{

    a.judgment();

    a.dimension();

    cout<<"三角形a的面积为: "<<a.s<<endl;

}

catch (string &err)

{

    cout<<err<<endl;

}

catch(...)

{

    cout<<"错了伙计,你知道什么是三角形吗?"<<endl;

}

 

 

 

万能接收器要写在最后面。所有catch的最后一个,要么是你定义的catch () (没有万能的),要么是万能的catch(...)

如果你非要写在别的地方,那么。。重写编译器吧。

 

 

 

 

 

2:异常规范

当我看着在类中成员函数 void judgment()

{

    string yorn;

    if((a+b)<c ||(a+c)<b || (c+b)<a)

    {

        yorn="不是三角形";

        throw(yorn);

    }

}

时,我的心情澎湃,不能平静。会写抛出了,会写了,我要写两个,删一个留一个。。。等,两个throw,是的我还可以写200个throw,但是我要抛出什么类型呢?目前看来我只想抛出string类型的东西,万一我手快抛错了怎么办(没办法,菜鸟呀,菜鸟总有出错的时候!)。ok,查下资料,喝口小水,看看有没有解决的办法...(翻书中...)

 

 

 

 

 

工夫不负我有心人呀,翻出了异常规范这个语法。让我看看是怎么实现的

还是上诉的成员函数,改写成

void judgment() throw(string)

{

    string yorn;

    if((a+b)<c ||(a+c)<b || (c+b)<a)

    {

        yorn="不是三角形";

        throw(yorn);

    }

}

这样,就可以保证我只能抛出string类型的异常。

 

 

 

 

 

在函数的参数列表和函数体之间,throw()语句就是一个异常规范。

编译器保证不能抛出在throw()中包含的类型之外的异常。

比如,我们只想在函数中抛出的异常为int,string类型

我们就可以这样写我们的函数

 

viod myfun(int a,string b) throw(int ,string)

{

//函数实现

    ......

    throw(int类型)

    throw(string类型)

    throw(char类型)//想抛吗,估计抛不出来的,呵呵~~~~

    ......

}

这样,就保证我们在函数中只能抛出类型为int,和string的异常。

 

 

 

 

 

3:异常和继承

看代码先

#i nclude <iostream>

#i nclude <string>

#i nclude <math.h>

using namespace std;

 

class triangle :public exception//定义一个三角形的类

{

    public :

    float a,b,c,d;

    float s;

    public:

    triangle()

    {}

    triangle(float a1,float b1,float c1)

    {

      a=a1;

      b=b1;

      c=c1;

    }

    void judgment()  throw(exception)//判断是否是三角形

    {

        //任意两边和小于第三边,就不是三角形

      if((a+b)<c ||(a+c)<b || (c+b)<a)

       {

        throw exception("不是三角形,玩我呀大哥");

       }

    }

    void dimension()//计算面积

    {

      d=(a+b+c)/2;        //海伦公式

      s=sqrt(d*(d-a)*(d-b)*(d-c));

    }

};

void main()

{

    triangle a(7,2,3);

 

    try

    {

        a.judgment();

        a.dimension();

        cout<<"三角形a的面积为: "<<a.s<<endl;

    }

    catch(exception &e)

    {

        cout<<e.what()<<endl;

    }

}

 

 

 

上诉代码写的就是异常的继承,triangle继承自exceprion类,exceprion是c++类库的一个标准异常类,triangle类继承了对异常的处理,比如语句throw exception("不是三角形,玩我呀大哥");,这里抛出的是一个exception类型的异常,我们在接受的时候就要用catch (exception &e)来接受,并且使用了一个exption提供的一个what方法,来输入异常描述。

我们也可以不用类库中的exception类,自己来写一个异常处理的类。

下面是我写的一个功能很简单的异常处理类,我把它做为一个基类,用triangle来继承它

#i nclude <iostream>

#i nclude <string>

#i nclude <math.h>

using namespace std;

 

class exec

{

    private:

    string error;

    public:

    exec()

    {}

    exec(string err)

    {

        error=err;

    }

    string geterr()

    {

        return error;

    }

};

 

class triangle :public exec//定义一个三角形的类

{

    public :

    float a,b,c,d;

    float s;

    public:

    triangle()

    {}

    triangle(float a1,float b1,float c1)

    {

      a=a1;

      b=b1;

      c=c1;

    }

    void judgment()  throw(exec)//判断是否是三角形

    {

      //任意两边和小于第三边,就不是三角形

      if((a+b)<c ||(a+c)<b || (c+b)<a)

       {

        throw (exec("不是三角形,你玩我呀大哥"));

       }

    }

    void dimension()//计算面积

    {

      d=(a+b+c)/2;        //海伦公式

      s=sqrt(d*(d-a)*(d-b)*(d-c));

    }

};

void main()

{

    triangle a(7,2,3);

 

    try

    {

        a.judgment();

        a.dimension();

        cout<<"三角形a的面积为: "<<a.s<<endl;

    }

    catch(exec &e)

    {

        cout<<e.geterr()<<endl;

    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值