这是我的感觉,具体需要研究一下~

找到一篇文章:在构造和析构中抛出异常

测试验证在类构造和析构中抛出异常, 是否会调用该类析构.

如果在一个类成员函数中抛异常, 可以进入该类的析构函数.

  1. /// @file ClassroomExamples.cpp
  2. /// @brief xxxx-xxxx课堂笔记的验证代码
  3. /// 测试c++异常
  4. /// 在构造和析构中抛出异常
  5. #include <iostream>
  6. #include <limits>
  7. #include "MyException.h"
  8. #include "TestThrow.h"
  9. using namespace std;
  10. void clear_cin();
  11. void fnTest_terminate();
  12. // typedef void (__cdecl *terminate_function)()
  13. void my_terminate_function();
  14. void test_try_catch();
  15. /// 声明接口异常
  16. /// 在函数后面修饰 throw(x, y, z)
  17. /// 说明该函数要抛出哪种异常, 给调用者看的
  18. /// 函数后面的throw修改, 说明本函数要抛出什么类型的异常
  19. /// 但是M$并没有在函数中校验throw的类型是否和函数说明相同
  20. /// throw可以修饰一个函数中抛出的多个异常
  21. void fnOnTryCatch(char* pIn) throw(CMyException*, int);
  22. /// throw() 表明, 该函数保证不抛出任何异常
  23. void fnOnTryCatch1(char* pIn) throw();
  24. int main(int argc, char** argv, char** envp)
  25. {
  26. test_try_catch();
  27. // fnTest_terminate();
  28. cout << "END, press any key to quit" << endl;
  29. clear_cin();
  30. getchar();
  31. return 0;
  32. }
  33. void test_try_catch()
  34. {
  35. char* p = NULL;
  36. /// 如果没有catch能接住异常, 被OS接住后, 直接弹abort框
  37. /// CTestThrow Test1; ///< 模拟没有catch能接住异常的情况
  38. try
  39. {
  40. // 如果Test2的构造中抛出异常, CTestThrow中缺没能catch住异常, Test2的析构不会被调用
  41. CTestThrow Test2;
  42. fnOnTryCatch1(p); ///< 前面抛出了异常, 这句也就不会被执行.
  43. // fnOnTryCatch(p);
  44. }
  45. /// 用基类指针去捕获异常
  46. /// throw的是具体异常子类的指针
  47. catch (IMyExceptionBase* pe)
  48. {
  49. if (NULL != pe)
  50. {
  51. cout << pe->GetErrMsg() << endl;
  52. delete pe;
  53. pe = NULL;
  54. }
  55. }
  56. catch(...)
  57. {
  58. cout << "catch(...)" << endl;
  59. }
  60. }
  61. void fnOnTryCatch1(char* pIn)
  62. {
  63. if (NULL != pIn)
  64. {
  65. /// 但是M$并没有在函数中校验throw的类型是否和函数说明相同
  66. // throw((int)2); ///< M$
  67. *pIn = 'e';
  68. }
  69. }
  70. void fnOnTryCatch(char* pIn)
  71. {
  72. if (NULL == pIn)
  73. {
  74. // throw((int)2);
  75. /// 但是M$并没有在函数中校验throw的类型是否和函数说明相同
  76. // throw((double)3);
  77. throw(new CMyException("fnOnTryCatch (NULL == pIn)"));
  78. }
  79. *pIn = 't';
  80. }
  81. void fnTest_terminate()
  82. {
  83. // terminate(); ///< 调用了 abort
  84. set_terminate(my_terminate_function);
  85. terminate();
  86. }
  87. void my_terminate_function()
  88. {
  89. /// 可以做些收尾的事情
  90. cout << "my_terminate_function()" << endl;
  91. /// 如果不调用 exit, OS会调用abort, 很不体面的弹abort框
  92. exit(0); ///< 这样就不会弹框了
  93. }
  94. void clear_cin()
  95. {
  96. cin.clear();
  97. cin.sync();
  98. }
  1. // MyException.cpp: implementation of the CMyException class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "MyException.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. CMyException::CMyException(const char* pcErrMsg)
  9. :m_pcErrMsg(pcErrMsg)
  10. {
  11. }
  12. CMyException::~CMyException()
  13. {
  14. }
  15. const char* CMyException::GetErrMsg()
  16. {
  17. return m_pcErrMsg;
  18. }
  1. // MyException.h: interface for the CMyException class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_MYEXCEPTION_H__96603384_DB81_48CE_8173_29BC2A82F26A__INCLUDED_)
  5. #define AFX_MYEXCEPTION_H__96603384_DB81_48CE_8173_29BC2A82F26A__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include "MyExceptionBase.h"
  10. class CMyException : public IMyExceptionBase
  11. {
  12. public:
  13. CMyException(const char* pcErrMsg);
  14. virtual ~CMyException();
  15. virtual const char* GetErrMsg(); ///< 接口, 取错误消息
  16. private:
  17. const char* m_pcErrMsg;
  18. };
  19. #endif // !defined(AFX_MYEXCEPTION_H__96603384_DB81_48CE_8173_29BC2A82F26A__INCLUDED_)
  1. // MyExceptionBase.cpp: implementation of the CMyExceptionBase class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "MyExceptionBase.h"
  5. //////////////////////////////////////////////////////////////////////
  6. // Construction/Destruction
  7. //////////////////////////////////////////////////////////////////////
  8. IMyExceptionBase::IMyExceptionBase()
  9. {
  10. }
  11. IMyExceptionBase::~IMyExceptionBase()
  12. {
  13. }
  1. // MyExceptionBase.h: interface for the CMyExceptionBase class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_MYEXCEPTIONBASE_H__90DA9DC6_7686_417F_801B_2DC4F1E7A3C5__INCLUDED_)
  5. #define AFX_MYEXCEPTIONBASE_H__90DA9DC6_7686_417F_801B_2DC4F1E7A3C5__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. class IMyExceptionBase
  10. {
  11. public:
  12. IMyExceptionBase();
  13. virtual ~IMyExceptionBase() = 0;
  14. virtual const char* GetErrMsg() = 0; ///< 接口, 取错误消息
  15. };
  16. #endif // !defined(AFX_MYEXCEPTIONBASE_H__90DA9DC6_7686_417F_801B_2DC4F1E7A3C5__INCLUDED_)
  1. // TestThrow.cpp: implementation of the CTestThrow class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include <stddef.h>
  5. #include <iostream>
  6. using namespace std;
  7. #include "TestThrow.h"
  8. #include "MyException.h"
  9. //////////////////////////////////////////////////////////////////////
  10. // Construction/Destruction
  11. //////////////////////////////////////////////////////////////////////
  12. CTestThrow::CTestThrow()
  13. {
  14. /// 构造函数失败时, 可以抛出异常
  15. /// 假设资源分配失败, 要抛出异常
  16. /// 如果抛出的异常, 没有被我们的catch接住, 被OS接住后, 直接弹abort框
  17. /// 在类中抛出异常后, 如果没有在类中catch住, 就不会自动调用析构.
  18. /// 如果在类中需要抛出异常, 而且本类没有catch能接住该异常,
  19. /// 要先释放能释放的资源, 才能throw异常
  20. /// 必须在构造函数中的try中抛出异常的类
  21. /// 才会在本类生命期结束的时候, 自动析构
  22. /// 如果被其他作用域的catch捕获, 本类的析构不会被调用
  23. throw(new CMyException("failed CTestThrow::CTestThrow()"));
  24. }
  25. CTestThrow::~CTestThrow()
  26. {
  27. /// 析构函数中, 从语法上讲, 是不应该抛出异常的
  28. /// 如果一个类已经在销毁了, 可是有问题, 我们也做不了什么
  29. /// 所以 : 析构函数不应该抛出异常
  30. // throw(new CMyException("failed CTestThrow::~CTestThrow()"));
  31. cout << "CTestThrow::~CTestThrow()" << endl;
  32. }
    1. // TestThrow.h: interface for the CTestThrow class.
    2. //
    3. //////////////////////////////////////////////////////////////////////
    4. #if !defined(AFX_TESTTHROW_H__573ED8BA_B817_440C_9D67_14CBCA9EA6FC__INCLUDED_)
    5. #define AFX_TESTTHROW_H__573ED8BA_B817_440C_9D67_14CBCA9EA6FC__INCLUDED_
    6. #if _MSC_VER > 1000
    7. #pragma once
    8. #endif // _MSC_VER > 1000
    9. class CTestThrow
    10. {
    11. public:
    12. CTestThrow();
    13. virtual ~CTestThrow();
    14. };
    15. #endif // !defined(AFX_TESTTHROW_H__573ED8BA_B817_440C_9D67_14CBCA9EA6FC__INCLUDED_)

http://blog.csdn.net/lostspeed/article/details/50439069

C++不能中断构造函数来拒绝产生对象(在构造和析构中抛出异常)的更多相关文章

  1. STL—对象的构造与析构

    STL内存空间的配置/释放与对象内容的构造/析构,是分开进行的.   对象的构造.析构         对象的构造由construct函数完成,该函数内部调用定位new运算符,在指定的内存位置构造对象 ...

  2. C++对象的构造、析构与拷贝构造

    今天下午在研究虚函数的时候遇到了一个问题,觉得很有意思,记录一下. 先看代码: class Base { public: Base(int value) { m_nValue = value; cou ...

  3. 【C++】类和对象(构造与析构)

    类 类是一种抽象和封装机制,描述一组具有相同属性和行为的对象,是代码复用的基本单位. 类成员的访问权限 面向对象关键特性之一就是隐藏数据,采用机制就是设置类成员的访问控制权限.类成员有3种访问权限: ...

  4. C++程序设计方法3:派生类对象的构造和析构过程

    基类中的数据成员,通过继承成为派生类对象的一部分,需要在构造派生类对象的过程中调用基类构造函数来正确初始化: 若没有显示调用,则编译器会自动生成一个对基类的默认构造函数的调用. 若想要显示调用,则只能 ...

  5. c++中在一个类中定义另一个只有带参数构造函数的类的对象

    c++中在一个类中定义另一个只有带参数构造函数的类的对象,编译通不过 #include<iostream> using namespace std; class A { public:  ...

  6. c++——对象的构造和析构函数、构造函数的分类及调用

    1构造函数和析构函数的概念 有关构造函数 1构造函数定义及调用 1)C++中的类可以定义与类名相同的特殊成员函数,这种与类名相同的成员函数叫做构造函数: 2)构造函数在定义时可以有参数: 3)没有任何 ...

  7. new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例。

    new运算符 - JavaScript | MDN https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operator ...

  8. C++(二十六) — 构造函数、析构函数、对象数组、复制构造函数

    1.构造函数 (1)每个类都要定义它自己的构造函数和析构函数,是类的成员函数. 特点:名称与类名相同:没有返回值:一定是共有函数,可以直接访问类内所有成员函数:可以带默认形参,可以重载: class ...

  9. 使用构造函数 Boolean 创造的对象不是布尔值,而是对象,typeof new Boolean(1) == 'object'

    注意,使用构造函数 Boolean 创造的对象不是布尔值: 事实上 new Boolean() 返回的是一个 Boolean 对象: typeof new Boolean(1) == 'object' ...

随机推荐

  1. 腾讯QQ企业邮箱POP3/SMTP设置

    腾讯企业邮箱支持通过client进行邮件管理. POP3/SMTP协议 收发邮件server地址分别例如以下. 接收邮件server:pop.exmail.qq.com (port 110) 发送邮件 ...

  2. MVCC

    http://blog.chinaunix.net/xmlrpc.php?id=3886838&r=blog/article&uid=26664667

  3. 提取DLL类库代码

    @SET destFolder=.\bin@XCOPY /I /Y %SYSTEMDRIVE%\WINDOWS\assembly\GAC_MSIL\Microsoft.ReportViewer.Pro ...

  4. [iOS 开发] app无法访问本地相册,且不显示在设置 -隐私 - 照片中

    近几天在使用iOS8的Photos Framework访问本地相册时,app即不会弹出是否允许访问提示框,也无法显示在iPhone的设置-隐私-照片的访问列表中,代码如下: PHAuthorizati ...

  5. MySQL存储过程学习笔记

    MySQL在5.0以前并不支持存储过程,这使得MySQL在应用上大打折扣.MySQL 5.0终于开始支持存储过程了. MySQL的关键字大小写通用.该学习笔记对关键字使用大写:变量名,表名使用小写. ...

  6. hadoop集群环境搭建准备工作

    一定要注意hadoop和linux系统的位数一定要相同,就是说如果hadoop是32位的,linux系统也一定要安装32位的. 准备工作: 1 首先在VMware中建立6台虚拟机(配置默认即可).这是 ...

  7. maven提示错误的解决办法

    import或者new一个的maven project的时候,提示如下错误 Description    Resource    Path    Location    TypeCannot read ...

  8. Use StringBuilder instead of String as possible as you can.

    If you are care a littile about the time your algorithm cost,you should notice that,you my use Strin ...

  9. iOS Instruments之Core Animation动画性能调优(工具复选框选项介绍)

    Core Animation工具用来监测Core Animation性能.它给我们提供了周期性的FPS,并且考虑到了发生在程序之外的动画(见图12.4) Core Animation工具提供了一系列复 ...

  10. SpringMVC4+thymeleaf3的一个简单实例(篇三:页面参数获取)

    本篇将通过示例介绍页面参数是如何传递到后台的.我们继续沿用之前搭好的程序结构,如果你不知道,请参照前两篇.为方便跳转页面,我们在首页以及zoolist.html页面都加上彼此地址的链接:首页: zoo ...