未捕获和意外的异常处理

一、未捕获异常:

    如果没有任何一个层次的异常处理器能够捕获某种异常,则一个特殊的库函数terminate()(在头文件<exception>中定义)会被自动调用。默认情况下terminate()函数调用标准C库函数abort()使程序执行异常终止而退出。

    abort()函数不会调用正常的终止函数,全局对象和静态对象的析构函数不会执行。

    terminate()函数还会在如下两种情况下执行:

(1)局部对象的析构函数抛出异常时,栈正在进行清理工作,即栈反解的过程中。

(2)全局对象或静态对象的构造函数或析构函数抛出一个异常。

通过set_terminate()函数,可以设置自己的terminate()函数。

二、意外异常:

如果函数所抛出的异常,没有列在异常规格说明的异常集中,一个特殊的函数unexpected()将会被调用。默认的unexpected()函数会调用terminate()函数。

通过set_unexpected()函数可以设置自己的函数来响应意外的异常。

如果unexpected处理器所抛出的异常还不符合函数的异常规格说明,以下两种情况之一将会发生:

(1)如果函数的异常规格说明中包括std::bad_exception,unexpected处理器所抛出的异常会被替换成std::bad_exception对象,然后程序恢复到这个函数被调用的位置重新开始异常匹配。

(2)如果函数的异常规格说明中不包括std::bad_exception,程序会调用terminate()函数。

例子如下:

#include <iostream>
#include <stdlib.h>
using namespace std;

class A{};
class B{};

void my_thandler()
{
    cout<<"terminate called"<<endl;
    exit(0);
}

void my_uhandler1() {throw A();}
void my_uhandler2() {throw;}

void t() {throw B();}
void f() throw (A) {t();}
void g() throw(A,bad_exception) {t();}

int main()
{
    set_terminate(my_thandler);
    set_unexpected(my_uhandler1);
    try
    {
        f();
    }
    catch(A&)
    {
        cout<<"caught an A from f"<<endl;
    }

    set_unexpected(my_uhandler2);

    try
    {
        g();
    }
    catch(bad_exception&)
    {
        cout<<"caught a bad_exception from g"<<endl;
    }

    try
    {
        f();
    }
    catch(...)
    {
        cout<<"this will never print"<<endl;
    }
    return 0;
}

在上例中,f()声明抛出一个A类型的异常,但是t()缺抛出了一个B类型的异常,调用了用户设置的my_uhandler1,在其中抛出了一个A类型的异常,重新异常匹配,则匹配成功。

g()声明抛出A类型和std::bad_exception类型的异常,初次的异常匹配失败,调用了用户设置的my_uhandler2,其中把捕获到的异常重新抛出,此时仍然不符合g()的异常规格说明,但其中有std::bad_exception异常,故被替换为此类型的异常。

在第三部分中,f()抛出了异常规格说明中未声明的异常类型,故调用了my_thandler(),程序终止退出。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值