C++ 异常处理(throw、try、catch)

参考《C++ Primer 第五版》P172

一、throw表达式

一个简单的例子:

#include <iostream>
using namespace std;

int main()
{
    int a=5,b=0;
    if(b==0)
        throw b;    //抛出异常
    return 0;
}

//output:
terminate called after throwing an instance of 'int'

C++标准库定义了一组类,用于报告标准库函数遇到的问题。其中 exception 头文件定义了最通用的异常类 exception。它只报告异常的发生,不能提供任何额外信息。示例如下:

#include <iostream>
using namespace std;

int main()
{
    int a=5,b=0;
    if(b==0)
        throw exception();
    return 0;
}

//output:
terminate called after throwing an instance of 'std::exception'
  what():  std::exception

可以看到 exception 只能提供系统的报错信息,那么如何添加自己写的错误信息呢?可以用 头文件定义的其他异常类,比如 runtime_error,表示只有在运行时才能检测出的问题。示例如下:

#include <iostream>
using namespace std;

int main()
{
    int a=5,b=0;
    if(b==0)
        throw runtime_error("Error: b=0");
    return 0;
}

//output:
terminate called after throwing an instance of 'std::runtime_error'
  what():  Error: b=0

在控制台输出了自己添加的报错语句:Error: b=0,其中 what() 是C++异常类型唯一定义的成员函数,该函数没有任何参数,返回值是一个 const char* 的字符串。

二、try语句块(try–catch语句)

使用ry语句块时,C++异常处理的流程为:

throw(抛出异常)–> try(检测异常) --> catch(捕获异常)

异常必须显式地抛出(throw),才能被检测(try)和捕获(catch)到;如果没有显式的抛出,即使有异常也检测不到。

所以必须使用 throw 关键字来显式地抛出异常,并且用catch捕获异常时,catch和throw的数据类型必须一致,否则无法捕获异常。

try语句块的格式为:

try {
	...
} 
catch (...) {
	...
}

需要注意的是try之后可以跟多个catch子句,而不止一个。

用法示例:

#include <iostream>
using namespace std;

//整数相除
double func(int a,int b){
    if(b==0)
        throw b;     //抛出异常,数据类型为 int 
    double res=static_cast<double>(a)/b;    //数据类型转换
    return res;
}

int main()
{
    int a=5,b=3,c=0;
    try
    {
        double result=func(a,b);    //没有异常
        cout<<a<<"/"<<b<<"= "<<result<<endl;
        result=func(a,c);          //有异常
    }
    catch (int)    //捕获异常
    {
        cerr<<"Error: c=0"<<endl;    //cerr是标准错误流,用于输出错误信息
    }
    return 0;
}

//output:
5/3= 1.66667
Error: c=0

其中的 catch (int)表示捕获 throw 抛出的数据类型为 int 的异常。

当然throw可以以抛出其他数据类型的异常,我们稍作修改,将 throw b 修改为 throw “Error: b=0”,相应的catch也需要作出修改,代码如下:

#include <iostream>
using namespace std;

//整数相除
double func(int a,int b){
    if(b==0)
        throw "Error: b=0";    //抛出异常,数据类型为what()成员函数的返回值类型 const char*
    double res=static_cast<double>(a)/b;    //数据类型转换
    return res;
}

int main()
{
    int a=5,b=3,c=0;
    try
    {
        double result=func(a,b);    //没有异常
        cout<<a<<"/"<<b<<"= "<<result<<endl;
        result=func(a,c);    //有异常
    }
    catch (const char*)    //捕获异常
    {
        cerr<<"Error: c=0"<<endl;
    }
    return 0;
}

//output:
5/3= 1.66667
Error: c=0

这样可能会感觉比较麻烦,因为我们需要确定 throw抛出的异常的数据类型。有一种更见的方法是使 throw 抛出异常类,比如:

throw runtime_error(“Error: b=0”);
catch (runtime_error)

这样 catch 只需要捕获 runtime_error即可。

代码示例:

#include <iostream>
using namespace std;

//整数相除
double func(int a,int b){
    if(b==0)
        throw runtime_error("Error: b=0");    //抛出runtime_error异常
    double res=static_cast<double>(a)/b;
    return res;
}

int main()
{
    int a=5,b=3,c=0;
    try
    {
        double result=func(a,b);    //没有异常
        cout<<a<<"/"<<b<<"= "<<result<<endl;
        result=func(a,c);    //有异常
    }
    catch (runtime_error)    //捕获异常
    {
        cerr<<"Error: c=0"<<endl;
    }
    return 0;
}

//output:
5/3= 1.66667
Error: c=0
  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ctrl A_ctrl C_ctrl V

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值