由 C++的异常处理联想到RAII
来源:互联网 发布:ubuntu怎么使用命令 编辑:程序博客网 时间:2024/06/11 02:42
在传统的C语言,我们通过检查函数的返回值以判断调用是否成功,并处理各类异常情况,在Unix环境下可以通过设置error变量发出错误消息,并通过setjmp, longjmp来跳出深层次调用。C++语言在此基础上引入了Exception机制,遇到异常的程序模块可以throw一个异常,其他方法可以通过try catch来捕捉该异常。但是相比后来的Java与C#中的异常处理机制,C++的还是有不少待完善的地方:
1,缺少Exception基类,任何类都可以作为作为异常被抛出,且可以抛出对象,引用或者指针。
2,没有像Java那样约束方法,强制要求其处理或者抛出其内部所有可能发生的异常。比如:调用该方法的其他程序模块根本无法从接口中判断其是否会抛出异常,也就不会注意处理其异常。
正因为这样,造成C++程序员很少会使用其异常机制,我通常还是按照C语言的方式,利用返回值来区分各类错误,有时候偶尔在类的构造函数中会使用异常,因为在构造函数中产生的错误可能会造成生成的对象不正常,而构造函数没有返回值,因此只能抛出异常,或者设置一个状态标志位。
此外C++中异常机制的一大弊端就是会造成资源泄漏,比如:
void f()
{
Resource * r = new Resource();
FILE * f = fopen(“datafile.txt”);
DoSomething(); //这里可能会抛出异常,造成后面的代码无法执行,资源得不到及时释放。
delete r;
fclose(f);
}
为了解决资源泄漏的问题,当然不仅仅是因为异常引起的,还有可能是在程序编写过程中,某些地方不小心直接return了,或者为了避免在每一个返回语句前都加上一段delete, fclose之类的语句。在此我们需要用的C++的RAII机制:
RAII: Resource Acqusition is Initialization资源申请即初始化
其利用的原理就是堆栈上的对象在离开作用域时均会被自动调用析构函数,因此我们可以在构造函数中直接申请资源,在析构函数中释放资源,从而保证资源始终能够得到正常释放。
比如:
class File
{
public:
File(const char * file_name) { f = fopen(file_name); ….}
~File() {fclose(f);}
int write(const char *data, int len);
int read(char *data, int len);
private:
FILE *f;
}
另外std::auto_ptr也是基于这个原理构造的。
还有一点要提出的是,有些人喜欢在构造函数中将资源初始化为空,单独使用其他的方法来申请资源,比如在上述File的构造函数中令f=NULL,再添加一个open()方法来打开文件,我个人认为这是没有必要的,因为如果这样的话,那么在write与read方法中肯定每次都需要判断f是否不为NULL。具体的应用见仁见智,因此在C#与Java中貌似很多都有默认什么都不干的构造函数
- 由 C++的异常处理联想到RAII
- 由百度关键词联想联想到的
- 由机器联想到联想
- 由内存的使用联想到的
- 由修电脑联想到的
- 由MMX优化联想到的
- 由Passbook联想到Path的盈利模式
- 由vijos1067 联想到的矩阵乘法
- 由servlet联想到struts
- 由币市联想到
- 由兔子的笑话联想到的哲理
- 由兔子的笑话联想到的哲理
- 由windows的Alt+Tab键联想到的数据结构
- 由整型数据的宽度联想到的
- 由HTTP的\r\n所联想到的
- 由Jobs的联想
- 由触摸屏所联想到的软件界面设计
- 由《函数式编程另类指南》联想到的哲学思想
- MTK个人入门笔记(有关菜单树)
- 大量大学视频教程,要自学充电的朋友好好看看了
- C++ 头文件中为何添加了#ifndef #define #endif还会出现变量重复定义的问题
- TCP/DUP 找出最合适的MTU值
- 数据的查询、模糊查询、新建、修改、删除
- 由 C++的异常处理联想到RAII
- 2010 05 16
- NO.30 要你命3000-宕机问题面面观:3.案例-三方交互未设置连接、读取超时时间
- Linux操作系统下如何添加服务
- QT 实现图像处理-傅立叶变换、傅立叶反变换、平滑、锐化与模板匹配
- MCS-51指令系统
- 工作上的一些总结,送给工作3-5年的朋友们,共勉
- 重载转换操作符
- CAD快捷键一览表