C++细节梳理之异常处理

Try-Catch 执行机制

将可能抛出异常的程序段嵌在 try 块保护段之中。控制通过正常的顺序执行到达 try块,然后执行 try 子块内的保护段。如果在保护段执行期间没有引发异常,那么跟在try子块后的catch子句就不执行。程序会继续执行紧跟在try块中最后一个catch子句后面的语句。

若程序有异常,则通过 throw 关键字创建一个异常对象,并抛出。

catch子句按其在try块后出现的顺序被检查。类型匹配的catch子句将捕获throw抛出的对象并处理异常(或继续抛出异常)。

如果找不到匹配的处理代码,则自动调用标准库函数terminate,其默认功能是调用abort( ) 终止程序。

try块

我们只需将可能有问题的代码块放入try块中,若有问题则会抛出异常,try块会停止运行

try{
    可能有问题的代码
}

throw关键字

throw 表达式; 
throw; //用于当前异常再抛出
表达式可以是任意类型的对象,抛出时会复制被抛出的对象为临时对象,作为异常对象,如果此时在try块中,则会终止try执行,转而执行catch语句捕获
异常的种类很多,并且有继承关系
异常中有一个what()函数,当我们想要修改what()函数的内容时可以这样做
throw std::out_of_range("Index out of range");

在throw后面接上异常的类型,然后在括号内写下想输出的字符串

try {
        ...

    } catch (const std::out_of_range& e) {
        cout << e.what();
    }

若try中出现异常就会输出该字符串

Index out of range

catch

catch紧接着try块写,将会捕捉类型相同的异常

catch (std::bad_alloc& ba)
{
    std::cerr << "bad_alloc caught: " << ba.what() << '\n';
}

cerr是用于异常的输出,这里用cout也行

catch括号内首先说明异常的类型,并注意这里要使用异常对象的引用!

但是异常的种类实在太多了,我们一个个写的话太麻烦了,catch还提供一种模式

catch (...)
{
    ...
}

在括号内写三个"."表示所有类型的异常,该catch可以捕获所有类型的异常,所以必须是最后的catch。

在catch捕获的顺序中,子类应该在基类前面

异常传播

在函数调用的时候,若当前函数未处理异常(catch没有相符合的类型),则会将该异常交给调用函数

void f3(int x) {
switch (x) {
case 1: throw 3.4; // 抛出double型异常
case 2: throw 2.5f; // 抛出float型异常
case 3: throw 1; // 抛出int型异常
case 5: throw exception(); //抛出标准异常
}
cout << "End of f3" << endl;
}

void f2(int x) {
try {
f3(x);
}
catch (int) { //int型异常的处理代码
cout << "An int exception occurred!--from f2" << endl; 
}
catch (float) { //float型异常的处理代码
cout << "A float exception occurred!--from f2" << endl;
}
cout << "End of f2" << endl;
}

void f1(int x) {
try {
f2(x);
}
catch (int) { // int型异常的处理代码
cout << "An int exception occurred!--from f1" << endl;
}
catch (float) { // float型异常的处理代码
cout << "A float exception occurred!--from f1" << endl;
}
catch (double) { // double型异常的处理代码
cout << "A double exception occurred!--from f1" << endl;
}
cout << "End of f1" << endl;
}

int main()
{
for (int i = 1; i < 6; i++) {
cout << "-------- intput i = " << i << endl;
f1(i);
}
cout << "End of main" << endl;
return 0;
}

执行上面的代码我们会得到这样的输出

-------- intput i = 1
A double exception occurred!--from f1
End of f1
-------- intput i = 2
A float exception occurred!--from f2
End of f2
End of f1
-------- intput i = 3
An int exception occurred!--from f2
End of f2
End of f1
-------- intput i = 4
End of f3
End of f2
End of f1
-------- intput i = 5
terminate called after throwing an instance of 'std::exception'
what(): std::exception

可以看见,f2没有double型,所以将异常传递给了f1,因此没有输出“End of f2”

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值