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

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

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

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

  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. nanosleep纳秒级延迟

    //函数原型 int nanosleep(struct timespec *req, struct timespec *rem) //参数列表: // req:要求的睡眠时间 // rem:剩余的睡眠 ...

  2. ||和 && 符号的赋值运用(转)

    javascript “||”.“&&”的灵活运用 博客分类: Jquery javascript javascript中运用“||”.“&&”javascript 真 ...

  3. android 27 ListView

    效果: 上图中ArrarAdapter是数组的适配器,CursorAdapter是游标适配器,用于操作数据库的数据. ListView是垂直列表,数据源是集合或者数组,这些View都是安卓里的Adap ...

  4. 韩玉琪 《Linux内核分析》MOOC课程

    http://www.cnblogs.com/hyq20135317/p/5422516.html http://mooc.study.163.com/course/USTC-1000029000

  5. [转] 考验你的JavaScript底细

    http://sentsin.com/ 尽管今日的JavaScript已经突飞猛进,但JS的许多特性仍然保留,以下题目并不是有意设坑,许多地方将验证你的JS底细,如果错了一半,请别告诉我你从事前端. ...

  6. struts2 OGNL 表达式

    一.Struts 2支持以下几种表达式语言: OGNL(Object-Graph Navigation Language),可以方便地操作对象属性的开源表达式语言:JSTL(JSP Standard ...

  7. 分享一下自己在用的CSS样式重置代码

    通过借鉴网上大牛们的经验和自己在工作中碰到的一些问题,总结出了这些比较常用的CSS样式重置的代码: @charset "utf-8"; /* 防止用户自定义背景颜色对网页的影响,添 ...

  8. Axiom3D学习日记 2.介绍SceneManager,SceneNode,Entity

    SceneManager(场景管理类) 所有出现在屏幕里的东西都受SceneManager管理(最好是这样),当你放置对象在场景里,SceneManager就会跟踪他们的位置,当你为场景创建一个相机, ...

  9. Css3 常见鼠标滑过效果集合

    1.演示地址: http://yaochuxia.github.io/hover/#

  10. HTML5 Media事件

    Media 事件 由媒介(比如视频.图像和音频)触发的事件(适用于所有 HTML 元素,但常见于媒介元素中,比如 <audio>.<embed>.<img>.< ...