学习程序的好方法是阅读代码和改进代码。
下面的程例来自《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 == 0) throw 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 == 0) throw 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 }

C++异常处理小例的更多相关文章

  1. linux 命令小例

    xargs示例: ls |xargs -i mv {}  /opt find示例: find -mtime +n -name “*.avi” -type f -exec rm {} \; find - ...

  2. Ubuntu13.04 Eclipse下编译安装Hadoop插件及使用小例

    Ubuntu13.04 Eclipse下编译安装Hadoop插件及使用小例 一.在Eclipse下编译安装Hadoop插件 Hadoop的Eclipse插件现在已经没有二进制版直接提供,只能自己编译. ...

  3. 使用libcurl下载文件小例

    libcurl是一个很强大的开源网络处理库,支持包括HTTP.HTTPS.FTP……一系列网络协议.用它来进行HTTP的get\post 或者下载文件更是小菜一碟,chrome内核都用到了它,本文主要 ...

  4. webpack -- 多页面简单小例

    有时单页面并不能满足我们的业务需求,就需要去构建多页面应用,以下为简单小例: entry:{ index:'./src/module/index/index.js', student:'./src/m ...

  5. [libpng]CMake+VS2015下编译libpng,及使用小例

    编译前的工作 在编译libpng前,需要把zlib编译好,并加载到编译环境里. CMake + VS2015 下编译zlib,及使用小例 下载与解压 libpng的官网是 http://www.lib ...

  6. HTML5基础小结(二)——标签小例

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amlhaGFuNjI5NjI5/font/5a6L5L2T/fontsize/400/fill/I0 ...

  7. js入门学习~ 运动应用小例

    要实现的效果如下: 鼠标移入各个小方块,实现对应的效果(变宽,变高,移入透明,移出恢复)~~ (且各运动相互之前不干扰)  主要是练习多个物体的运动框架~~ --------------------- ...

  8. js中的冒泡排序以及实现一个数组中得最到最大的数字小例

    这其实是一个很简单的js就可以实现,当然一般情况就是利用for循环,从第一个跟第二个开始比较,根据大小交互位置,思路很简单. 也就是js中的冒泡排序 冒泡排序 时间复杂度为O(n^2),有两个优点: ...

  9. linux之C编程实战小例

    人生匆匆一趟,打不打酱油?怎么打?怎么打"质量好点的酱油"?由你决定.打酱油是一种态度,更是一种生活! 哈哈,事不关己不开口,专心一意打酱油! 请记住下面些许话: 不要一味的说别人 ...

随机推荐

  1. 设计模式(十一):FACADE外观模式 -- 结构型模式

    1. 概述 外观模式,我们通过外观的包装,使应用程序只能看到外观对象,而不会看到具体的细节对象,这样无疑会降低应用程序的复杂度,并且提高了程序的可维护性.例子1:一个电源总开关可以控制四盏灯.一个风扇 ...

  2. VS2013单元测试

    原文地址:http://www.luacloud.com/2014/vs2013-unit-test-generator.html 下载地址:http://visualstudiogallery.ms ...

  3. 使用Horner法则计算多项式的值

    计算Pn(x) = an * x^n + an-1 * x^(n-1) + ... + a1 * x + a0 直接计算,需要做的乘法次数 1+2+3+……+n = n(1+n)/2 = O(n2) ...

  4. convert app to 64-bit for ios7

    https://developer.apple.com/library/ios/documentation/General/Conceptual/CocoaTouch64BitGuide/Introd ...

  5. MKMapView and Zoom Levels: A Visual Guide

    原帖:http://troybrant.net/blog/2010/01/mkmapview-and-zoom-levels-a-visual-guide/ So, how exactly does ...

  6. python游戏编程——跟13岁儿童学编程

    python爬虫基本告一段落,琢磨搞点其他的,正好在网上看到一个帖子,一个外国13岁小朋友用python写的下棋程序,内容详细,也有意思,拿来练手. 13岁啊.. 我这年纪还在敲 dir啥的吧 想到原 ...

  7. 170109、JSONP是什么

    一.JSONP的诞生 首先,因为ajax无法跨域,然后开发者就有所思考 其次,开发者发现, <script>标签的src属性是可以跨域的 把跨域服务器写成 调用本地的函数 ,回调数据回来不 ...

  8. 关于使用百度ueditor时的一些问题

    本来这些问题直接在百度贴吧里回答不就完事了,可是好死不死的,百度贴吧里老出现 未知错误,错误号:230274 看来还是算了,自己做一个随笔记录一下好了 关于我们获取里面的内容时,老是会有一个<p ...

  9. [Javascript] Array methods in depth - indexOf

    indexOf is used to search for a value or reference inside of an array. In this lesson we first look ...

  10. Java基础知识强化33:String类之String类的获取功能

    1. String类的获取功能 int length() // 获取字符串中字符的个数(长度) char charAt(int index)//根据位置获取字符 int indexOf(int ch) ...