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

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

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

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

  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. android自定义控件,动态设置Button的样式

    原文  http://www.cnblogs.com/landptf/p/4562203.html 今天来看一个通过重写Button来动态实现一些效果,如圆角矩形.圆形.按下改变字体,改变背景色,改变 ...

  2. Linux之TCPIP内核参数优化

    /proc/sys/net目录 所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失),例如下面这 ...

  3. Qt c++11

    借助 Qt 5 的信号槽语法,我们可以将一个对象的信号连接到 Lambda 表达式,例如:     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // !!! Q ...

  4. Qt 学习之路:QML 基本元素

    QML 基本元素可以分为可视元素和不可视元素两类.可视元素(例如前面提到过的Rectangle)具有几何坐标,会在屏幕上占据一块显示区域.不可视元素(例如Timer)通常提供一种功能,这些功能可以作用 ...

  5. requireJS入门

    RequireJS 下载地址 : http://requirejs.org 什么是 requireJS ?以下是官方网站上的解释: RequireJS is a JavaScript file and ...

  6. xslt语法之---If Else

    大家都知道,XSL中是没有if else的,那么要想实现if else该怎么办呢? 其实很简单 <xsl:choose> <xsl:when test="position( ...

  7. Android(java)学习笔记206:利用开源SmartImageView优化网易新闻RSS客户端

    1.我们自己编写的SmartImageView会有很多漏洞,但是我们幸运的可以在网上利用开源项目的,开源项目中有很多成熟的代码,比如SmartImageView都编写的很成熟的 国内我们经常用到htt ...

  8. U3D 内置对象

    在U3D里面提供了一个Time对象: void OnGUI(){ Debug.Log("########################"); GUILayout.Label (& ...

  9. 【转】iOS开发之各种动画各种页面切面效果

    原文: http://www.cnblogs.com/ludashi/p/4160208.html?utm_source=tuicool 因工作原因,有段时间没发表博客了,今天就发表篇博客给大家带来一 ...

  10. js 中读取JSON的方法探讨

    方法一:函数构造定义法返回 var strJSON = "{name:'json name'}";  //得到的JSONvar obj = new Function("r ...