C++异常处理

C++异常处理涉及到三个关键字:trycatchthrow

        throw:用于抛出异常

        catch:用于捕捉异常

        try:块中的代码标识将被激活的特定异常。它后面通常跟着一个或多个 catch 块。

如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码。执行一个throw时,throw之后的语句将不再被执行(类似于return),程序会跳到与之匹配的catch模块。

代码示例:

int test(int a,int b)
{
    if (b == 0)
    {
        throw "ERROR b = 0";
    }
    return(a/b);

}

int main()
{
    int a = 0;
    //test(4,0);不捕捉异常,直接运行,会出现段错误

    try
    {
        a = test(4,0);
    }
    catch(const char* msg) 
    {
        cout<<msg<<endl;
    }
}

C++的标准异常:

C++ å¼å¸¸çå±æ¬¡ç»æ

异常描述
std::exception该异常是所有标准 C++ 异常的父类。
std::bad_alloc该异常可以通过 new 抛出。
std::bad_cast该异常可以通过 dynamic_cast 抛出。
std::bad_exception这在处理 C++ 程序中无法预期的异常时非常有用。
std::bad_typeid该异常可以通过 typeid 抛出。
std::logic_error理论上可以通过读取代码来检测到的异常。
std::domain_error当使用了一个无效的数学域时,会抛出该异常。
std::invalid_argument当使用了无效的参数时,会抛出该异常。
std::length_error当创建了太长的 std::string 时,会抛出该异常。
std::out_of_range该异常可以通过方法抛出,例如 std::vector 和 std::bitset<>::operator[]()。
std::runtime_error理论上不可以通过读取代码来检测到的异常。
std::overflow_error当发生数学上溢时,会抛出该异常。
std::range_error当尝试存储超出范围的值时,会抛出该异常。
std::underflow_error当发生数学下溢时,会抛出该异常。

示例代码:

int test(int a,int b)
{
    if (b == 0)
    {
        throw std::bad_exception();
    }
    return(a/b);

}

int main()
{
    int a = 0;

    try
    {
        a = test(4,0);
    }
    catch(bad_exception) 
    {
        cout<<"catch bad_exception"<<endl;
    }
    printf("1--------------\n");

    try
    {
        a = test(4,0);
    }
    catch(...)//省略号表示捕捉任意类型的异常
    {
        cout<<"catch exception"<<endl;
    }
    printf("2--------------\n");
    
    try
    {
        a = test(4,0);
    }
    catch(domain_error)  //不会捕捉到这个异常
    {
        cout<<"domain_error"<<endl;
    }
    catch(bad_exception) 
    {
        cout<<"catch bad_exception"<<endl;
    }
    printf("3--------------\n");

    try
    {
        a = test(4,0);
    }
    catch(domain_error)   //只捕捉domain_error类型的异常,与抛出的异常类型不一致,引发程序段错误
    {
        cout<<"domain_error"<<endl;
    }
    printf("4--------------\n");
}

catch语句是按照出现顺序逐一匹配的,越是专门的catch越应该置于catch列表的前端。因此当程序使用具有继承关系的多个异常时,必须对catch语句的顺序进行组织和管理,使得派生类的异常处理代码在基类异常处理代码之前。

我们可以通过继承和重载 exception 类来定义新的异常。下面的实例演示了如何使用 std::exception 类来实现自己的异常:

示例代码:

struct myException : public exception
{
    const char * what () const throw ()
    {
        return "my exception";
    }
};


int test(int a,int b)
{
    if (b == 0)
    {
        throw bad_exception();
    }
    else if (b == 1)
    {
        throw myException();
    }
    
    return(a/b);

}

int main()
{
    int a = 0;

    try
    {
        a = test(4,1);
    }
    catch(myException &b) 
    {
        cout<<"myException"<<endl;
        cout<<b.what()<<endl;    //把异常的信息打印出来
    }
    printf("1--------------\n");

    try
    {
        a = test(4,0);
    }
    catch(bad_exception &b) 
    {
        cout<<"bad_exception"<<endl;
        cout<<b.what()<<endl;  //把异常的信息打印出来
    }
    printf("2--------------\n");
}

what() 是异常类提供的一个公共方法,它已被所有子异常类重载。这将返回异常产生的原因。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值