标准C++异常处理

标准C++异常处理(EH)
    EH引入了3个新的C++语言关键字:
    catch、throw、try。
    异常通常通过下列语句触发
    A.throw [expr] 函数通过“异常规格申明”定义它将抛出什么异常
    B.throw ([type-ID-list]) 可选项type-ID-list包含一个或多个类型的名字,以逗号分割。这些异常靠try块中的异常处理函数进行捕获。
    try compound-statement handler-sequence
    处理函数队列包含一个或多个处理函数,形式如下:
    catch ( exception-declaration ) compound-statement
    处理函数的“异常申明”指明了这个函数将捕获什么类型的异常。
    跟在try 和catch 后面的语句必须刮在{}内,而整个try 块组成一条完整的大语句。

void f() throw(int, some_class_type)
{
    int i;
    // ... generate an 'int' exception
    throw i;
// ...
}
int main()
{
    try
    {
        f();
    }
    catch(int e)
    {
    // ... handle 'int' exception ...
    }
    catch(some_class_type e)
    {
    // ... handle 'some_class_type' exception ...

    }
    // ... possibly other handlers ...
    return 0;
}

    异常规格申明是EH 特有的,。一个空的异常规格申明表明函数不抛出任何异常:
    void f() throw()
    {
    //throw no exception
    }
    如果函数没有异常规格申明,它可以抛出任何类型的异常:
    void f()
    {
    // ... function can throw anything or nothing ...   
    }
    当函数抛异常时,关键字throw 通常后面带一个被抛出的对象:
    throw i;
    然而,throw 也可以不带对象:
    catch(int e)
    {
        // ... handle 'int' exception ...
        throw;
    }
    它的效果是再次抛出当前正被捕获的对象(int e)。因为空throw 的作用是再次抛出已存在的异常对象,所以它必须位于catch 语句块中。MFC 也有再次抛出异常的功能,SEH则没有,它没有将异常对象交给过处理函数,所以没什么可再次抛出的。
    就象函数原型中的参数申明一样,异常申明也可以是无名的:
    catch(char *)
    {
        // ... handle 'char *' exception ...
    }
    当这个处理函数捕获一个char *型的异常对象时,它不能操作这个对象,因为这个对象没有名字。
    异常申明还可以是这样的特殊形式:
    catch(...)
    {
        // ... handle any type of exception ...
    }
    就象不定参数中的“...”一样,异常申明中的“...”可以匹配任何异常的类型。   

    1.标准异常对象的类型
    在C++标准库中,有些函数抛出特定的异常,而另外一些根本不抛任何异常。
    因为C++标准中没有明确规定,所以C++的库函数可以抛出任何对象或不抛。但C++标准推荐运行库的实现通过抛出定义在<stdexecpt>中的异常类型或其派生类型来报告错误:

namespace std
{
    class logic_error; // : public exception
    class domain_error; // : public logic_error
    class invalid_argument; // : public logic_error
    class length_error; // : public logic_error
    class out_of_range; // : public logic_error

    class runtime_error; // : public exception
    class range_error; // : public runtime_error
    class overflow_error; // : public runtime_error
    class underflow_error; // : public runtime_error
}

    这些(异常)类只对C++标准库有约束力。在你自己的代码中,你可以抛出(和捕获)任何你所象要的类型。
    标准库头文件<exception>申明几个EH类型和函数:

namespace std
{
//
// types
//
class bad_exception;
class exception;
typedef void (*terminate_handler)();
typedef void (*unexpected_handler)();
//
// functions
//
terminate_handler set_terminate(terminate_handler) throw();
unexpected_handler set_unexpected(unexpected_handler) throw();
void terminate();
void unexpected();
bool uncaught_exception();
}

    exception是所有标准库抛出的异常的基类
    uncaught_exception()函数在异常被抛出却没有被捕获时返回true,其他情况返回faslse。
    terminate()是EH的应急处理。它在异常处理体系陷入了不可恢复状态时被调用,经常是因为试图重入(在前一个异常正处理过程中又抛了一个异常)。
    unexpected()在函数抛出一个它没有在“异常规格申明”中申明的异常时被调用。这个预料外的异常可能在退栈过程中被替换为一个bad_excetion 对象。
    运行库提供了缺省terminate_handler()和unexpected_handler() 函数处理对应的情况。你可以通过set_terminate()和set_unexpected()函数替换库的默认版本。

    EH运行于异常生命期的五个阶段:
    A.程序或运行库遇到一个错误状况(阶段1)并且抛出一个异常(阶段2)。
    B.程序的运行停止于异常点,开始搜索异常处理函数。搜索沿调用栈向上搜索。
    C.搜索结束于找到一个异常申明于异常对象的静态类型相匹配(阶段3)。于是进入相应的异常处理函数。
    D.异常处理函数结束后,跳到此异常处理函数所在的try块下面最近的一条语句开始执行(阶段5)。这个行为意味着C++标准中异常总是终止。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值