技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 算法 --> 僵尸对象或 RAII

僵尸对象或 RAII

浏览:2417次  出处信息

    我最近在想这个问题,到底要不要在程序中使用异常?

    以前写的 C 代码比较多,即使写 C++,基本上也是把它当成 C with object 来用。对异常的了解偏少,使用更是极少。最近评审别人代码的时候遇到一个问题:如果构造函数中 new 失败了,会发生什么事情?

    工程的代码一般提倡哪里出错在哪里处理,不能恢复的要返回错误码给调用者。在一般情况下,使用 new(std::no_throw) 保证 new 不抛出异常(否则结果是灾难性的),并且检查分配是否成功是可以实现这一点的。

    遗憾的是构造函数没有返回值,我们不能返回构造失败。那么只有用迂回的办法,为类定义一个成员变量 bool inited。初始化为 false,只有在构造的工作都完成之后,才将它置为 true。如果一个对象的 inited 成员为 false,就意味着它构造过程中出了问题,不能被使用。这就是一个僵尸对象,“活死人”。

    看,我们成功地规避了使用异常。但是慢着,不是只有 bad_alloc 这一个异常啊!还有 bad_cast、runtime_error、logic_error,还有:

$ grep class /usr/include/c++/4.5/stdexcept
// Standard exception classes  -*- C++ -*-
// ISO C++ 19.1  Exception classes
   *  program runs (e.g., violations of class invariants).
   *  @brief One of two subclasses of exception.
  class logic_error : public exception
  class domain_error : public logic_error
  class invalid_argument : public logic_error
  class length_error : public logic_error
  class out_of_range : public logic_error
   *  @brief One of two subclasses of exception.
  class runtime_error : public exception
  class range_error : public runtime_error
  class overflow_error : public runtime_error
  class underflow_error : public runtime_error 

    天那,我未曾注意过标准库有那么多异常!那么如果在使用标准库时,不小心触发了什么异常,OMG!

    这样看来,使用异常是很有必要的。但是,麻烦的问题又来了,一旦使用异常,函数的退出过程就变了。使用错误码有一个好处,就是你可以在函数返回前擦干净自己的屁股;但是使用异常呢?你既要保证对象能够自己擦屁股(RAII),还要保证函数能自己擦屁股(在正确的位置使用异常处理),这样才能在 stack unwinding 时不会导致内存泄露。

    还有一个麻烦是,你要遵从约定――特别是对于一个程序库作者来说。如果约定出错时抛出异常,那么可以抛;如果约定出错时返回错误码,或者这个库可能被 C 调用,那么抛出异常就可能是灾难。

    现在看来,如果想实现更健壮的 C++ 程序,那么异常处理是不可或缺的。但在使用异常处理之前,必须得了解在哪里、怎样抛出和捕获异常,如果是团队合作,可能还需要有简单的操作指导手册,否则使用不当或者过量的异常也可能带来麻烦。

    我还在路上!

建议继续学习:

  1. PHP的异常原理与实例说明 Fatal error: Uncaught exception    (阅读:8821)
  2. 是返回错误码,还是抛出异常?说说我的选择    (阅读:5878)
  3. Perl 异常处理之 autodie 和 Try::Tiny    (阅读:2619)
  4. PHP程序员也要学会使用“异常”    (阅读:2569)
  5. 异常的代价    (阅读:2445)
  6. PHP错误处理及异常处理    (阅读:2460)
  7. 深入理解PHP之异常机制    (阅读:2387)
  8. 我们什么时候应该使用异常?    (阅读:2349)
  9. Java处理InterruptedException异常小结    (阅读:1737)
  10. Swift错误和异常处理    (阅读:813)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1