zoukankan      html  css  js  c++  java
  • 外传篇2 函数的异常规格说明

    1.异常规格说明

    (1)问题:如何判断一个函数是否会抛出异常,以及抛出哪些异常?

    (2)异常规格说明

    • C++提供语法用于声明函数所抛出的异常

    • 异常声明作为函数声明的修饰符写在参数列表后面

          

    (3)异常规格说明的意义:

    • 提示函数的调用者必须做好异常处理的准备

    • 提示函数的维护者不要抛出其它异常

    • 异常规格说明函数接口的一部分

    (4)问题:如果抛出的异常不在声明列表中,会发生什么?

    下面的代码的输出什么?
          

    编程实验:异常规格之外的异常

    #include <iostream>
    
    using namespace std;
    
    void func() throw(int)
    {
        cout << "func()";
        cout << endl;
        
        throw 'c';
    }
    
    int main()
    {
        try
        {
            func();
        }
        catch(int)
        {
            cout << "catch(int)";
            cout << endl;
        }
        catch(char)
        {
            cout << "catch(char)";
            cout << endl;
        }
        
        return 0;
    }

    运行结果:不同编译器运行结果不一样

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    func()
    terminate called after throwing an instance of 'char'
    Aborted (core dumped)

    2.unexpected() 函数

    (1)unexpected() 函数

    • 函数抛出异常不在规格说明中,全局 unexpected() 被调用

    • 默认的 unexpected() 函数会调用全局的 terminate() 函数

    • 可以自定义函数替换默认的 unexpected() 函数实现

    • 注意:不是所有的C++编译器都支持这个标准行为

    (2)unexpected() 函数的替换:

    • 自定义一个无返回值无参数的函数

      • 能够再次抛出异常
        1. 当异常符合触发函数的异常规格说明时,恢复程序执行

        2. 否则,调用全局 terminate() 函数结束程序

    • 调用 set_unexpected () 设置自定义的异常函数

      • 参数类型为 void (*) ()

      • 返回值为默认的 unexpected() 函数入口地址

    编程实验:自定义 unexpected() 函数

    #include <iostream>
    #include <cstdlib>
    #include <exception>
    
    using namespace std;
    
    void my_unexpected()
    {
        cout << "void my_unexpected()" << endl;
        exit(1);
    }
    
    void func() throw(int)
    {
        cout << "func()";
        cout << endl;
        
        throw 'c';
    }
    
    int main()
    {
        set_unexpected(my_unexpected);
        
        try 
        {
            func();
        } 
        catch(int) 
        {
            cout << "catch(int)";
            cout << endl;
        } 
        catch(char) 
        {
            cout << "catch(char)";
            cout << endl;
        }
        
        return 0;
    }

    运行结果:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    func()
    void my_unexpected()


    编程实验2: 自定义 unexpected() 函数

    exit();改为throw 1;后的运行结果

    void my_unexpected()
    {
        cout << "void my_unexpected()" << endl;
        // exit(1);
        throw 1;
    }

    运行结果:

    [root@bogon Desktop]# g++ test.cpp
    [root@bogon Desktop]# ./a.out 
    func()
    void my_unexpected()
    catch(int)

    (程序恢复执行了)
    unexpected() 函数是正确处理异常的最后机会如果没有抓住这次机会,全局的 terminate() 函数就会被调用,当前程序就只能以异常结束告终。)

    3.小结

    • C++中的函数可以声明异常规格说明

    • 异常规格说明可以看作接口的一部分

    • 函数抛出异常不在规格说明中unexpected() 被调用

    • unexpected() 中能够再次抛出异常

      1. 异常能够匹配,恢复程序的执行

      2. 否则,调用 terminate() 结束程序

     
     
  • 相关阅读:
    Project Chameleon Work In Progress 14
    All about Project Chameleon
    网页中图片连续滚动代码 (转)
    一点感言
    一些常用javascript代码(转)
    asp.net(c#)的一个非常非常奇怪的问题
    用javascript拦截a标签的超链接执行
    asp.net中用TreeView控件实现无限分级的好办法
    windows7 安装ez usb基本驱动
    管道编程
  • 原文地址:https://www.cnblogs.com/hoiday/p/10222469.html
Copyright © 2011-2022 走看看