异常处理总结(一)

来源:互联网 发布:故宫纪录片知乎 编辑:程序博客网 时间: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)屏蔽这条警告。

原创粉丝点击