随笔 - 51, 文章 - 1, 评论 - 41, 引用 - 0
数据加载中……

CPPEXP —— 构造函数抛异常

说明

类的构造函数抛出异常,不会调用该类的析构函数,资源的释放原则是编译器申请的编译器负责,程序员申请的程序员负责。
在实验代码中,子类Except的构造函数抛出异常,则Base和mMember1的构造函数是编译器调用,因此编译器会调用它们的析构函数,而mMember2由程序员主动使用new生成,因此需要程序员主动使用delete。

解决方法:

  1. 在构造函数中使用try...catch结构
  2. 使用类包装资源申请,如auto_ptr。

实验代码

  1. /**
  2. * @file constructor_exception.cpp
  3. * @brief 测试构造函数异常引起的行为
  4. * @copyright public domain
  5. */
  6. #include <iostream>
  7. #include <exception>
  8. #include <memory>
  9. class Base {
  10. public:
  11. Base() { std::cout << "Base()" << std::endl; }
  12. virtual ~Base() { std::cout << "~Base()" << std::endl; }
  13. };
  14. class Member {
  15. public:
  16. Member(int id):mId(id) { std::cout << "Member():" << mId << std::endl; }
  17. virtual ~Member() { std::cout << "~Member()" << mId << std::endl; }
  18. protected:
  19. int mId;
  20. };
  21. class Except : public Base {
  22. public:
  23. Except() : mMember1(1), mMember2(NULL) {
  24. std::cout << "Except() enter" << std::endl;
  25. mMember2 = new Member(2);
  26. mMember3.reset(new Member(3));
  27. throw std::exception();
  28. std::cout << "Except() leave" << std::endl;
  29. }
  30. virtual ~Except() {
  31. delete mMember2;
  32. std::cout << "~Except()" << std::endl;
  33. }
  34. protected:
  35. Member mMember1;
  36. Member *mMember2;
  37. std::auto_ptr<Member> mMember3;
  38. };
  39. int main() {
  40. try {
  41. Except e;
  42. } catch (std::exception& e) {
  43. std::cout << e.what() << std::endl;
  44. }
  45. return 0;
  46. }

运行及结果

$ g++ constructor_exception.cpp 
$ ./a.out 
Base()
Member():1
Except() enter
Member():2
Member():3
~Member()3
~Member()1
~Base()
std::exception




posted on 2016-04-30 10:17 lemene 阅读(365) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理