异常

文章参考:爱编程的大丙 (subingwen.cn)

1. C++98

在C++98中,为程序可能出现的异常提供了一套完整的机制,其基本语法如下:

  • 抛出异常:

    throw 表达式;
    
  • try catch代码块:

    try{
    	复合语句
    }catch(异常类型){
        复合语句
    }catch(异常类型){
        复合语句
    }
    

抛出机制:

当函数发生异常要被抛出时,从进入try块开始,到throw异常之间在栈内构建的所有对象,都会被自动析构。析构的顺序与构造的顺序相反。这一过程被称为栈的解旋

异常接口声明:C++98为了增强程序可读性,可以在函数生命中列出那些可能抛出的异常类型,常有方式有三种:

  • 指定可以抛出的异常类型:在函数后加上throw(异常类型1, 异常类型2...)

    #include <iostream>
    #include <string>
    using namespace std;
    
    // 自己定义的异常类
    struct MyException{
        int code;
        string msg;
        MyException(int a, string s): code(a), msg(s){}
    };
    // 可以抛出MyException、int类型的异常
    double divide(int a, int b) throw (MyException, int){
        if(b == 0){
            throw MyException(1, "除数不能为0");
            // throw 1
        }
        return a/b;
    }
    
    int main(void){
        int a = 10;
        int b = 0;
        try{
            double result = divide(a, b);
        }
        catch(int e){
            cout << e << endl;
        }
        catch(MyException e){
            cout << e.code << "\t" << e.msg << endl;
        }
        return 0;
    }
    
  • 抛出任意类型的异常:在函数后不使用throw()即可。

    // 自己定义的异常类
    struct MyException{
        int code;
        string msg;
        MyException(int a, string s): code(a), msg(s){}
    };
    double divide(int a, int b){
        if(b == 0){
            throw MyException(1, "除数不能为0");
            // throw 1
        }
        return a/b;
    }
    
  • 不抛出异常:在函数后使用throw(),且不添加任何参数,表示该函数不允许抛出异常。

    // 自己定义的异常类
    struct MyException{
        int code;
        string msg;
        MyException(int a, string s): code(a), msg(s){}
    };
    double divide(int a, int b) throw()
    {
        if(b == 0){
            throw MyException(1, "除数不能为0");
            // throw 1
        }
        return a/b;
    }
    

2. C++11

在C++11中,对C++98中异常的逻辑进行了修改:

  • 弃用了显式声明抛出的异常类型(这本来就很少使用)。禁止在在函数后加上throw(异常类型1, 异常类型2...)

  • 使用noexcept替代throw()来声明函数不会抛出异常。

    noexceptthrow()的不同之处在于:如果使用noexcept修饰的函数出现了异常,编译器会直接调用std::terminate()函数来终止程序的运行,而异常处理机制throw()则会带来一些额外的开销,例如栈解旋

noexcept形式:有两种形式:

  • 直接在函数后添加该关键字即可。

  • 使用一个可接受的常量表达式作为参数:

    double divisionMethod(int a, int b) noexcept(常量表达式);
    

    该常量表达式结果会被转化为一个bool类型的值,对应如下:

    • true:表示函数不会抛出异常
    • false:表示有可能抛出异常这里
    • 不带常量表达式的noexcept相当于声明了noexcept(true),即不会抛出异常。
posted @   BinaryPrinter  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示