异常处理总结(一)
来源:互联网 发布:故宫纪录片知乎 编辑:程序博客网 时间:2024/04/30 07:57
对于初学软件开发的人来说,异常处理的重要性往往会被很多人所忽视。在正规化的软件开发过程中,异常处理往往扮演了一个重要的角色。我自己学习软件开发也有两年了,在此之前没有意识到异常处理的重要性。于是为此查了一些资料,重新学习了一下异常处理。在此总结一下学习成果。
一般的,传统错误处理方法大致可以分为返回码机制和全局变量两种。
1。返回码机制
这种处理错误的方法比较实用和简单,这也是我以前经常采取的手段之一。对于小型的程序来说这种异常处理机制的缺点暴露不明显,对于一个需要多人开发的软件程序来说,它的弊端就非常明显了!因为对于一个模块的实现者来说有的人返回值0代表错误;有的人返回值0代表正确,非0代表错误。解决方法可以用一致性的条文来控制。通常的,这些返回码就在一个公共的.h文件中以宏的形式存在。这样暂时解决了团队之间的一致性,但是这些都不是标准,兼容性太差。对于如此多的返回码要分别解释各自的意义,从调用者的角度来说,需要分别对返回码进行检查来处理异常,这样的代码往往就显得非常的臃肿,大大降低了可读性。
2。全局变量
通过用一个全局变量来表示一次操作是否成功。这个方法在多线程中就非常头痛。另外在每次处理完异常之后就要复位这个变量,如果忘记这个步骤,就会引起其他操作的误解。
C++的异常处理机制弥补了传统错误处理方法的弊端,当然它的代价就是性能上的消耗。但是换来了代码质量的改进,提高了代码间的维护性,这种消耗完全值得。
结构化异常处理和C++异常处理的区别:
结构化异常处理(SEH)是可用于任何编程语言的操作系统设备。而异常处理只能用于编写C++代码。如果在编写C++程序,应该使用C++异常处理而不是SEH。理由是C++异常处理是语言的一部分,编译器知道C++类对象是什么。也就是编译器能够自动生成代码来调用C++对象析构函数,保证对象的清除。但是也应该知道VC编译器已经利用操作系统的SEH实现了C++异常处理。所以当建立一个try块时,编译器就生成一个__try块。一个catch变成了SEH异常过滤器,并且catch中的代码变成了__except块中的代码。每写一条throw语句时,编译器就生成一个对windows的RaiseException函数的调用。用于throw语句的变量传递给RaiseException作为附加的参数。对于SEH的详细说明在《Windows核心编程》的第23章有详细介绍。
在使用C++异常处理的时候要注意几点:
1.异常的类型要一致。(见function1)
2.对于传递大型类对象时尽量使用引用的方式。(见function1)
3.尽量保持try块中抛出的异常在被处理的状态(提供足够的catch子句)(见function2)
class PrintErr
{
public:
PrintErr(int i) {m_iNum = i;}
int m_iNum;
};
class TypeErr{};
void Myprint(char* p) throw(PrintErr)
{
if(p == NULL)
throw PrintErr(10);
//...
}
void function1()
{
try
{
Myprint(NULL);// 抛出一个PrintErr的异常
}
// catch(int i) { /*..*/ } 异常的类型要一致
catch(PrintErr& err)// 使用引用的方式传递异常,防止不必要的拷贝大型类对象
{
//...
throw;// 如果异常在这里无法完成,可以rethrow这个异常(throw err)
}
catch(...)// 对于其他类型的异常进行处理
{
}
}
void function2()
{
try
{
Myprint(NULL);
}
// 没有为PrintErr提供catch子句,系统自动调用库函数terminate()。
catch (TypeErr& err)
{
//...
}
}
void function3() throw()// 这个函数被定义成不抛出任何异常
{
Myprint(NULL);// error
}
int main(int argc, char* argv[])
{
try
{
function1();
}
catch (PrintErr& err)
{
//...对rethrow的异常进行处理
}
return 0;
}
通常使用Visual C++编译异常处理时会出现warning C4290: C++ Exception Specification ignored。这是因为Visual C++在编译期检查异常规范申明,但在运行期忽略它们。你可以给函数加上异常申明,编译器会正确地分析它们,但在运行期这个申明没有效果,就象根本没有写过。所以可以使用#pragma warning(disable:4290)屏蔽这条警告。
- 异常处理总结(一)
- 异常处理总结(一)
- 异常处理总结(一)
- 异常处理之总结一
- 异常处理(一)
- (一)异常处理
- 异常处理(一、前言)
- c++异常处理(一)
- C++ 异常处理(一)
- JAVA异常处理(一)
- java异常处理(一)
- 异常处理框架(一)
- java异常处理(一)
- 异常处理总结(二)
- 异常处理总结(三)
- C#中的异常处理(一)
- C#中的异常处理(一)
- C#中的异常处理(简单)一
- 一小段摘抄
- Python 于 webgame 的应用(上)
- 临时对象的来源
- basex - XML数据库 浅谈
- 偏执狂的原创伤感日志:珍惜你们的缘分;幸福
- 异常处理总结(一)
- 注index buffers和vertex buffers不能同时使用D3DPOOL_MANAGED和D3DUSAGE_DYNAMIC创建
- IOS开发之关键字synchronized
- vc6.0配置头文件,和库文件
- 不是读后感的读后感
- 贪财的富翁
- Android Vers & its APIs、CuteName
- Tomcat配置: The archive: /bin/bootstrap.jar which is referenced by the classpath, does not exist.
- 详解MYSQL数据库密码的加密方式及破解方法