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

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

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

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

  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. bt 介绍以及 bt 种子的hash值(特征值)计算

    bt种子的hansh值计算,近期忽然对bt种子感兴趣了(原因勿问) 1. bt种子(概念) bt 是一个分布式文件分发协议,每一个文件下载者在下载的同一时候向其他下载者不断的上传已经下载的数据,这样保 ...

  2. hibernate批量删除和更新数据

    转载自:http://blog.csdn.net/yuhua3272004/article/details/2909538 Hibernate3.0 採用新的基于ANTLR的HQL/SQL查询翻译器, ...

  3. RGB的三维模型与渐变色-颜色系列之一

    一.前言 以下与颜色相关的日志记录了俺学习颜色的有关容,限于编写时的水平,难免存在缺点与错误,希望得到朋友.同行和前辈的指教,非常感谢.1.  RGB的三维模型与渐变色-颜色系列之一2.  <颜 ...

  4. JAVA获取随机数

    在Java中我们能够使用java.util.Random类来产生一个随机数发生器.它有两种形式的构造函数,各自是Random()和Random(long seed).Random()使用当前时间即Sy ...

  5. 设置ViewController 数据源无法改变view

    病情描述: viewController创建的时候勾选了xib,然后在显示的时候调用了如下语句: MTDetailDealViewController *detailController = [[MT ...

  6. RHEL7重置root密码

    一.rd.break方法 在linux16那一段的最后,空一格输入rd.break 按Ctrl+启动到单用户模式,如下: 进去后输入命令mount,发现根为/sysroot/,并且不能写,只有ro=r ...

  7. iOS图片压缩

    项目中常会遇到,上传图片的操作,由于iPhone手机直接拍照的图片往往比较大,一般3-4M,如果直接上传不做处理会浪费用户很多流量,再者有很多场景并不需要高清图片,所以在上传图片前对图片进行压缩,是很 ...

  8. Eclipse中点击小猫提示Tomcat settings should be set in Tomcat Preference Page

    1.window->preference->tomcat->tomcat-version选择自己tomcat版本 tomcat home 选择tomcat安装目录,即bin的上一层 ...

  9. Orace数据库锁表的处理与总结<摘抄与总结三>

    当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误. TX锁等待的分析 Oracle数据库中一般使用行级锁. 当Oracle ...

  10. 自己动手写一个iOS 网络请求库的三部曲[转]

    代码示例:https://github.com/johnlui/Swift-On-iOS/blob/master/BuildYourHTTPRequestLibrary 开源项目:Pitaya,适合大 ...