快速业务通道

C++中的异常(exception)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
去向,那么在运行时刻如何确定。在 bar()中,一列catch就象switch语句中的case一样排列,实际上是一系列的判断 过程,依次检查当前异常的类型是否满足catch指定的类型,这种动态的,在运 行时刻确定类型的技术就是RTTI(Runtime Type Identification/Information) 。深度探索C++对象模型[1]中提到,RTTI就是异常处理的副产品。关于RTTI又是 一个话题,在这里就不详细讨论了。

3.2 是否继承std::exception?

是 的。而且std::exception已经有了一些派生类,如果需要可以直接使用它们,不 需要再重复定义了。

3.3 每个函数后面都要写throw()?

尽管前面已经分 析了这样做也有漏洞,但是它仍然是一个好习惯,可以让调用者从头文件得到非 常明确的信息,而不用翻那些可能与代码不同步的文档。如果你提供一个库,那 么在库的入口函数中应该使用catch(...)来捕获所有异常,在catch(...)中捕获 的异常应该被转换(rethrow)为throw列表中的某一个异常,这样就可以保证不 会产生意外的异常。

3.4 guard模式

异常处理在unwinding stack的时候 ,会析构所有栈上的对象,但是却不会自动删除堆上的对象,甚至你的代码中虽 然写了delete语句,但是却被throw跳过,导致内存泄露,或者其它资源的泄露 。例如:

void foo()
{
  ...
  MyClass * p = new MyClass();
  bar(p);
  ...
  delete p; // 如果bar()中抛出异常,则不会运行到这里!
}
void bar (MyClass * p)
{
  throw MyException();
}

对 于这种情况,C++提供了std::auto_ptr这个模板来解决问题。这个常被称为 “智能指针”的模板原理就是,将原来代码中的指针用一个栈上的模 板实例保护起来,当发生异常unwinding stack的时候,这个模板实例会被析构 ,而在它的析构函数中,指针将被delete,例如:

void foo()
{
  ...
  std::auto_ptr<MyClass> p(new MyClass ());
  bar(p.get());
  ...
  // delete p; // 这句不再需要了
}
void bar(MyClass * p)
{
   throw MyException();
}

不论bar()是否抛出异常,只要p被析 构,内存就会被释放。

不光对于内存,对于其他资源的管理也可以参照 这个方法来完成。在ACE[2]中,这种方式被称为Guard,用来对锁进行保护。

3.5 构造函数和析构函数

构造函数没有返回值,很多地方都推荐通过抛 出异常来通知调用者构造失败。这是肯定是个好的办法,但是也不很完美。主要 是因为在构造函数中抛出异常并不会引发析构函数的调用,例如:

class foo
{
public:
  ~foo() {} // 这个函数 将被调用
};
class bar
{
public:
  bar() { c_ = new char[10]; throw -1;}
  ~bar() { delete c_;} // 这个函 数不会被调用!
private:
  char * c_;
  foo f_;
};
void baz()
{
  try{
    bar b;
   }
  catch(int){
  }
}

在这个例子中,bar 的析构函数不会被调用,但是尽管如此,foo的析构函数还是可以被调用。危险 的是在构造函数中分配空间的c_,因为析构函数没有被调用而变成了leak。最好 的解决办法还是auto_ptr,使用auto_ptr后,bar类的声明变成:

class bar
{
public:
  bar() { c_.reset(new char[10]); throw -1;}
  ~bar() { } // 不需要再delete c_了!
private:
  auto_ptr<char> c_;
  foo f_;
};

析构函数中则不要抛出异常,这一点在Thinking In C++ Volume 2[3]中有明确表述。如果析构函数中调用了可能抛出异常的函数,则应该在析构 函数内部catch它。

3.6 什么时候使用异常

到现在为止,我们已经讨 论完了异常的大部分问题,可以实际操作操作了。实际应用中遇到的最让我头疼 的问题就是什么时候应该使用异常,是否应该用异常全面代替“简介 ”中提

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号