zoukankan      html  css  js  c++  java
  • C++异常处理小例

     
    学习程序的好方法是阅读代码和改进代码。
    下面的程例来自《An Overview of the C++ Programming Language》(5.1 异常和错误处理)
    程序用途:使用C++的异常机制,报告stack的上溢或者下溢。(我适当的把代码补全。)

    version 1 演示了基本的异常用法。
    从try里抛出一个异常(实例或对象),由catch里的类接受。

     1 version 1
     2 // From: An Overview of the C++ Programming Language
     3  
     4 #include <cstdlib>
     5 #include <iostream>
     6 #include <string>
     7 using namespace std;
     8 
     9 template<class T>class Stack{
    10     T* v;
    11     int max_size;
    12     int top;
    13 public:
    14     class Underflow{ };   // 下溢
    15     class Overflow{ };    // 上溢
    16     // construct function. determine the size   
    17     Stack(int s): max_size(s), top(0){ v = new T[max_size];}      
    18     ~Stack(){}
    19     void push(T c){
    20         if(top == max_size) throw Overflow();
    21         v[top++= c;
    22     }
    23     T pop(){
    24         if(top == 0throw Underflow();
    25         return v[--top];
    26     }
    27 }; 
    28 
    29 void f()
    30 {
    31     Stack<string> ss(10);
    32     try{
    33         ss.push("Quiz");
    34         string s = ss.pop();
    35         ss.pop();
    36     }
    37     catch(Stack<string>::Overflow){
    38         cerr << "error: stack overflow" << endl;
    39     }
    40     catch(Stack<string>::Underflow){
    41         cerr << "error: stack underflow" << endl;
    42     }
    43 }
    44 
    45 int main(int argc, char *argv[])
    46 {
    47     f();
    48     system("PAUSE");
    49     return EXIT_SUCCESS;
    50 }
    51 
    52 输出结果:error: stack underflow
    53 
    54 


    改进,我们的第二个版本如下:
    如果将

     1  class Underflow{ };   // 下溢
     2     class Overflow{ };    // 上溢
     3 
     4     catch(Stack<string>::Overflow){
     5         cerr << "error: stack overflow" << endl;
     6     }
     7     catch(Stack<string>::Underflow){
     8         cerr << "error: stack underflow" << endl;
     9     }
    10 


    分别改成如下:

     1 
     2     class Underflow{      //
     3     public:
     4         void error(void){
     5             cerr << "stack Underflow" << endl;
     6         }    
     7     };   
     8     class Overflow{       // 
     9     public:
    10         void error(void){
    11             cerr << "stack Overflow" << endl;
    12         } 
    13     };   
    14 
    15     catch(Stack<string>::Overflow& e){
    16         e.error();
    17     }
    18     catch(Stack<string>::Underflow& e){
    19         e.error();
    20     }
    21 

    改后的程序和原先的区别在哪里,看出来了吗? 呵呵呵。

    当然,我们还能将代码改进。这样产生了第三个版本。

    第三个版本:version3
    在Stack里面添加一个类class Stack_error,让Underflow和Overflow都继承它:

     1 template<class T>class Stack{
     2     //     
     3 public:
     4     class stack_error{
     5     public:
     6         virtual void error(void){  //当然,可以把它做成纯虚的。抽象类。
     7             cerr << "stack_error" << endl;
     8         }
     9     };
    10     class Underflow: public stack_error{      //
    11     public:
    12         void error(void){
    13             cerr << "stack Underflow" << endl;
    14         }    
    15     };   
    16     class Overflow: public stack_error{       // 
    17     public:
    18         void error(void){
    19             cerr << "stack Overflow" << endl;
    20         } 
    21     };   
    22     // 
    23 }
    24 
    接着把两个catch合并成一个catch,如下。
      try{
         
    // the same
        }
        
    catch(Stack<string>::stack_error& e){
            e.error();
        }

    这三个版本的功能是一样的,但版本越高,代码越清晰,代码也越容易维护。

    如果我们设计了一个库(比如上面的Stack),在开始的时候想到的就是两个异常,overflow和underflow。如果有version1和version3 这两种方法设计Stack,那么函数f()(用户的代码)也同样version1和version3。当一段日子过去了,我们准备再加入一个异常,比如midflow()(呵呵呵,我也想不出有什么类似的异常了)。这样的话,库设计者对用户说:“我们发现了midflow()异常,并加入库代码中,请您改写您的代码f()。”
    这样我们的version1得修改成如下形式:
    void f()
    {
        Stack
    <string> ss(10);
        
    try{
         
    //.
        }
        
    catch(Stack<string>::Overflow){
            cerr 
    << "error: stack overflow" << endl;
        }
        
    catch(Stack<string>::Underflow){
            cerr 
    << "error: stack underflow" << endl;
        }
        
    catch(Stack<string>::Midflow){    //我们的找到所有扑捉stack异常的代码,并加入这两句。
              cerr << "error: stack midflow" << endl;
        }
    }

    而version3由于midflow()继承了stack_error。而其接口还是一样,客户代码就无需更改了。

     完毕。鞠躬。 请多多交流!

    附:version3完整代码: 
     1 Version 3:
     2 #include <cstdlib>
     3 #include <iostream>
     4 
     5 using namespace std;
     6 
     7 template<class T>class Stack{
     8     T* v;
     9     int max_size;
    10     int top;
    11 public:
    12     class stack_error{
    13     public:
    14         virtual void error(void= 0;
    15     };
    16 
    17     class Underflow: public stack_error{      //
    18     public:
    19         void error(void){
    20             cerr << "stack Underflow" << endl;
    21         }    
    22     };   
    23     class Overflow: public stack_error{       // 
    24     public:
    25         void error(void){
    26             cerr << "stack Overflow" << endl;
    27         } 
    28     };   
    29     Stack(int s): max_size(s), top(0){ v = new T[max_size];}        // construct function. determine the size   
    30     ~Stack(){}
    31     void push(T c){
    32         if(top == max_size) throw Overflow();
    33         v[top++= c;
    34     }
    35     T pop(){
    36         if(top == 0throw Underflow();
    37         return v[--top];
    38     }
    39 }; 
    40 
    41 void f()
    42 {
    43     Stack<string> ss(0);
    44     try{
    45         ss.push("Quiz");
    46         string s = ss.pop();
    47         ss.pop();
    48     }
    49     catch(Stack<string>::stack_error& e){
    50         e.error();
    51     }
    52 
    53 }
    54 
    55 int main(int argc, char *argv[])
    56 {
    57     f();
    58     system("PAUSE");
    59     return EXIT_SUCCESS;
    60 }
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 交换Easy
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法提高 多项式输出
    Java实现 蓝桥杯VIP 算法训练 矩阵乘方
    QT中给各控件增加背景图片(可缩放可旋转)的几种方法
    回调函数实现类似QT中信号机制
    std::string的Copy-on-Write:不如想象中美好(VC不使用这种方式,而使用对小字符串更友好的SSO实现)
  • 原文地址:https://www.cnblogs.com/code-style/p/3330124.html
Copyright © 2011-2022 走看看