zoukankan      html  css  js  c++  java
  • C++ Primer chap11

    1

    异常使用示例:

    try { 

         for ( int ix = 1; ix < 51; ++ix ) 

         { 

             if ( ix % 3 == 0 ) 

                 stack.push( ix ); 

             if ( ix % 4 == 0 ) 

                 stack.display(); 

             if ( ix % 10 == 0 ) { 

                 int dummy; 

                 stack.pop( dummy ); 

                 stack.display(); 

             } 

         } 

    catch ( pushOnFull ) { ... } 

    catch ( popOnEmpty ) { ... } 

    其中的push, pop 在栈满和空时这样抛出异常:

    // 表达式是一个构造函数调用 

    throw popOnEmpty(); 

    当然,也可以抛出其他类型的对象。

     在我们的例子中 程序的控制流是下列几种情况之一  

            1    如果没有异常发生 则执行try 块中的代码 和try 块相关联的处理代码被忽略 程 

    序main()返回0     

            2    如果在for 循环的第一个if 语句中调用的成员函数push()抛出一个异常 则for 循环 

    的第二个和第三个if 语句被忽略 该for 循环和try 块被退出 执行pushOnFull 类型异常的 

    处理代码  

            3    如果在for 循环的第三个if 语句中调用的成员函数pop()抛出一个异常 则针对display() 

    的调用被忽略 for 循环和try 块被退出 执行popOnEmpty 类型异常的处理代码  

            当某条语句抛出异常时 跟在该语句后面的语句将被跳过 程序执行权被转交给处理异 

    常的catch 子句 如果没有catch 子句能够处理该异常 则程序执行权又将被转交给C++标准 

    库中定义的函数terminate()  。

    2

     C++的异常处理机制被称为是不可恢复的  nonresumptive      一旦异常被处理 程序的 

    执行就不能够在异常被抛出的地方继续 在我们的例子中 一旦异常被处理 程序的执行就 

    不能够在pop()成员函数中异常被抛出的地方继续 

    3

     异常对象总是在抛出点被创建 即使throw 表达式不是一个构造函数调用 或者它没有 

    表现出要创建一个异常对象 情况也是如此 例如  

    enum EHstate { noErr, zeroOp, negativeOp, severeError }; 

    enum EHstate state = noErr; 

    int mathFunc( int i ) { 

         if ( i == 0 ) { 

             state = zeroOp; 

             throw state; // 创建异常对象 

         } 

         // 否则, 正常处理流程继续 

            在这个例子中 对象state 没有被用作异常对象 而是由throw 表达式创建了一个类型为 

    EHstate 的异常对象 并且用全局对象state 的值初始化该对象 

    后面catch可以这样用:

    void calculate( int op ) { 

         try { 

             mathFunc( op ); 

         } 

         catch ( EHstate &eObj ) { 

             // eObj 是被抛出的异常对象的引用

         } 

    4

     throw 表达式的行为有点像函数调用 而catch 子句有点像函数定义 这两种机制的一个主要区别是  

    建立函数调用所需要的全部信息在编译时刻已经获得 而对异常处理机制则不然 C++异常 

    处理要求运行时刻的支持 

    5

    如果有一个异常被抛出 则资源res 的释放被跳过去 为保证该资源被释放 我们不是 

    为每种可能的异常都写一个catch 子句 因为我们不知道可能被抛出的全部异常 但是我们 

    可以使用catch 子句catch-all    这种catch 子句有一个形式为 ...    的异常声明 这里的二个点 

    被称为省略号 ellipsis      对任何类型的异常 都会进入这个catch 子句 例如  

    // 对任何异常都会进人 

    catch ( ... ) { 

         // 这里是我们的代码 

    6

    在异常处理过程中也可能存在 单个catch 子句不能完全处理异常 的情况 在某些修正动作之后 catch 子句

    可能决定该异常必须由函数调用链中更上级的函数来处理 那么catch子句可以通过重新抛出  rethrow   

     该异常 把异常传递给函数调用链中更上级的另一个catch 子句 

    rethrow 表达式的形式为  

    throw; 

            rethrow 表达式重新抛出该异常对象 rethrow 只能出现在catch 子句的复合语句中 例 

    如  

    catch ( exception eObj ) { 

         if ( canHandle( eObj ) ) 

             // 处理异常 

             return; 

         else 

             // 重新抛出它, 并由另一个 catch子句来处理 

             throw; 

    被重新抛出的异常就是原来的异常对象 

    7 异常规范  exception specification    提供 

    了一种方案 它能够随着函数声明列出该函数可能抛出的异常 它保证该函数不会抛出任何 

    其他类型的异常  

            异常规范跟随在函数参数表之后 它用关键字throw 来指定 后面是用括号括起来的异 

    常类型表 例如 我们可以如下修改iStack 类的成员函数的声明 以增加适当的异常规范  

    class iStack { 

    public: 

         // ... 

         void pop( int &value ) throw(popOnEmpty); 

         void push( int value ) throw(pushOnFull); 

    private: 

         // ... 

    }; 

            对于pop()的调用 保证不会抛出任何popOnEmpty 类型之外的异常 

  • 相关阅读:
    nginx入门
    nginx负载均衡算法
    Nginx+Tomcat搭建高性能负载均衡集群
    简单搭建dubbo
    webservice和restful的区别
    webservice、httpClient、dubbo的区别
    sublime 插件
    【exam answer 1】
    给定一个 1-100 的整数数组,请找到其中缺少的数字。
    Hibernate中clear()、evict()、flush()的方法使用说明
  • 原文地址:https://www.cnblogs.com/liujiahi/p/2196380.html
Copyright © 2011-2022 走看看