C++异常处理小例
下面的程例来自《An Overview of the C++ Programming Language》(5.1 异常和错误处理)
程序用途:使用C++的异常机制,报告stack的上溢或者下溢。(我适当的把代码补全。)
version 1 演示了基本的异常用法。
从try里抛出一个异常(实例或对象),由catch里的类接受。
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
改进,我们的第二个版本如下:
如果将
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
分别改成如下:
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都继承它:
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,如下。
// the same

}
catch(Stack<string>::stack_error& e){
e.error();
}
这三个版本的功能是一样的,但版本越高,代码越清晰,代码也越容易维护。
如果我们设计了一个库(比如上面的Stack),在开始的时候想到的就是两个异常,overflow和underflow。如果有version1和version3 这两种方法设计Stack,那么函数f()(用户的代码)也同样version1和version3。当一段日子过去了,我们准备再加入一个异常,比如midflow()(呵呵呵,我也想不出有什么类似的异常了)。这样的话,库设计者对用户说:“我们发现了midflow()异常,并加入库代码中,请您改写您的代码f()。”
这样我们的version1得修改成如下形式:
{
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完整代码:
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++异常处理小例的更多相关文章
- linux 命令小例
xargs示例: ls |xargs -i mv {} /opt find示例: find -mtime +n -name “*.avi” -type f -exec rm {} \; find - ...
- Ubuntu13.04 Eclipse下编译安装Hadoop插件及使用小例
Ubuntu13.04 Eclipse下编译安装Hadoop插件及使用小例 一.在Eclipse下编译安装Hadoop插件 Hadoop的Eclipse插件现在已经没有二进制版直接提供,只能自己编译. ...
- 使用libcurl下载文件小例
libcurl是一个很强大的开源网络处理库,支持包括HTTP.HTTPS.FTP……一系列网络协议.用它来进行HTTP的get\post 或者下载文件更是小菜一碟,chrome内核都用到了它,本文主要 ...
- webpack -- 多页面简单小例
有时单页面并不能满足我们的业务需求,就需要去构建多页面应用,以下为简单小例: entry:{ index:'./src/module/index/index.js', student:'./src/m ...
- [libpng]CMake+VS2015下编译libpng,及使用小例
编译前的工作 在编译libpng前,需要把zlib编译好,并加载到编译环境里. CMake + VS2015 下编译zlib,及使用小例 下载与解压 libpng的官网是 http://www.lib ...
- HTML5基础小结(二)——标签小例
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1amlhaGFuNjI5NjI5/font/5a6L5L2T/fontsize/400/fill/I0 ...
- js入门学习~ 运动应用小例
要实现的效果如下: 鼠标移入各个小方块,实现对应的效果(变宽,变高,移入透明,移出恢复)~~ (且各运动相互之前不干扰) 主要是练习多个物体的运动框架~~ --------------------- ...
- js中的冒泡排序以及实现一个数组中得最到最大的数字小例
这其实是一个很简单的js就可以实现,当然一般情况就是利用for循环,从第一个跟第二个开始比较,根据大小交互位置,思路很简单. 也就是js中的冒泡排序 冒泡排序 时间复杂度为O(n^2),有两个优点: ...
- linux之C编程实战小例
人生匆匆一趟,打不打酱油?怎么打?怎么打"质量好点的酱油"?由你决定.打酱油是一种态度,更是一种生活! 哈哈,事不关己不开口,专心一意打酱油! 请记住下面些许话: 不要一味的说别人 ...
随机推荐
- Qt自定义带游标的slider,在滑块正上方显示当前值(类似于进度条,用一个额外的QLabel冒充QSilder的一部分,然后move就行了)
首先自定义QSlider的子类MyCustomSlider,如下所示. mycustomslider.h #ifndef MYCUSTOMSLIDER_H #define MYCUSTOMSLIDER ...
- curl 提交请求
http://forums.phpfreaks.com/topic/194255-curl-sending-array-as-post-value/ http://www.cnblogs.com/ch ...
- python通过代理刷网页点击量
python通过代理刷网页点击量 更新异常处理情况 @time 2013-0803 更新循环里计数问题和随机等待时间问题 #!/usr/bin/python #-*- coding:utf-8 -*- ...
- Android豆瓣图书查询Demo
原文出自:方杰| http://fangjie.info/?p=26 转载请注明出处 首先先看一下Demo预览效果吧,主要也就是两个Activity.涉及到的技术有zxing开源项目的使用,网络协议豆 ...
- 40 个重要的 HTML5 面试问题及答案
本文将列出40个重要的HTML 5面试问题及答案,祝各位求职顺利. 目录 介绍 Canvas和SVG图形之间的区别是什么? 如何使用Canvas和SVG绘制矩形? 什么是CSS选择器? 如何使用ID值 ...
- ubuntu 创建eclipse 快捷方式
Ubuntu 上链接快捷方式,将想面内容复制并修改,命名为:eclipse.desktop #!/usr/bin/env xdg-open [Desktop Entry] Name=Eclipse C ...
- 解密UML九中关系
将UML中经常使用的九种关系分为了四组进行解释. 一.组合和聚合解说: 同样:均是指有部分组成总体. 不同:聚合是指能够独立存在的个体组成总体.(弱的拥有关系) 组合存在时间上的关系.总体和部分具有同 ...
- android源代码百度网盘分享
转载请标明出处: http://blog.csdn.net/yujun411522/article/details/46334123 本文出自:[yujun411522的博客] 近期在使用Ubunt ...
- boost之ThreadPool
threadpool是基于boost库实现的一个线程池子库,但线程池实现起来不是很复杂.我们从threadpool中又能学到什么东西呢? 它是基于boost库实现的,如果大家对boost库有兴趣,看看 ...
- QT中关于窗口全屏显示与退出全屏的实现
近期在学习QT时遇到了很多问题这也是其中一个,个人通过在各种书籍和网络上的查阅找到了一些关于这方面的答案,希望能给大家一些帮助. 首先,在QT中对于窗口显示常用的有这么几个方法可以调用: Qt全屏显示 ...