构造函数和析构函数中得异常处理
2016-01-10 21:46
218 查看
一. 构造函数
总结如下:
1. 构造函数中抛出异常,会导致析构函数不能被调用,但对象本身已申请到的内存资源会被系统释放(已申请到资源的内部成员变量会被系统依次逆序调用其析构函数)。
2. 因为析构函数不能被调用,所以可能会造成内存泄露或系统资源未被释放。
3. 构造函数中可以抛出异常,但必须保证在构造函数抛出异常之前,把系统资源释放掉,防止内存泄露。(如何保证???使用auto_ptr???)
试验代码:
二. 析构函数
参照《Effective C++》中条款08:别让异常逃离析构函数。
总结如下:
1. 不要在析构函数中抛出异常!虽然C++并不禁止析构函数抛出异常,但这样会导致程序过早结束或出现不明确的行为。
2. 如果某个操作可能会抛出异常,class应提供一个普通函数(而非析构函数),来执行该操作。目的是给客户一个处理错误的机会。
3. 如果析构函数中异常非抛不可,那就用try catch来将异常吞下,但这样方法并不好,我们提倡有错早些报出来。
本文参考:
1. 《Effective C++》条款08:别让异常逃离析构函数。
2. C++构造函数中抛出的异常
http://blog.csdn.net/deyili/article/details/6332760
3. C++ 构造函数抛出异常会引起内存泄漏吗?:
http://blog.csdn.net/sxf_824/article/details/4926687
4. 构造函数中可不可以抛出异常?析构函数呢?
http://blog.csdn.net/panlong1987/article/details/1835454 5. 是否能在构造函数,析构函数中抛出异常? http://www.cnblogs.com/KevinSong/p/3323372.html
总结如下:
1. 构造函数中抛出异常,会导致析构函数不能被调用,但对象本身已申请到的内存资源会被系统释放(已申请到资源的内部成员变量会被系统依次逆序调用其析构函数)。
2. 因为析构函数不能被调用,所以可能会造成内存泄露或系统资源未被释放。
3. 构造函数中可以抛出异常,但必须保证在构造函数抛出异常之前,把系统资源释放掉,防止内存泄露。(如何保证???使用auto_ptr???)
试验代码:
//ExceptionConstructor.h #pragma once #include <stdexcept> class CExceptionConstructor { public: CExceptionConstructor(); ~CExceptionConstructor(); }; class CExceptionAlpha { public: explicit CExceptionAlpha(int age) throw(std::invalid_argument); ~CExceptionAlpha(); private: int m_Age; }; class CExceptionBeta { public: explicit CExceptionBeta(int height) throw(std::invalid_argument); ~CExceptionBeta(); private: int m_Height; }; class CExceptionGroup { public: explicit CExceptionGroup(int count) throw(std::invalid_argument); ~CExceptionGroup(); private: CExceptionAlpha m_Alpha; CExceptionBeta m_Beta; int m_Count; };
//ExceptionConstructor.cpp #include "ExceptionConstructor.h" CExceptionConstructor::CExceptionConstructor() { } CExceptionConstructor::~CExceptionConstructor() { } CExceptionAlpha::CExceptionAlpha(int age) { if (age < 0 || age > 200) throw std::invalid_argument("Alpha invalid argument"); m_Age = age; printf("CExceptionAlpha construct!\n"); } CExceptionAlpha::~CExceptionAlpha() { printf("CExceptionAlpha desconstruct!\n"); } CExceptionBeta::CExceptionBeta(int height) { if (height < 5 || height > 500) throw std::invalid_argument("Beta invalid argument"); m_Height = height; printf("CExceptionBeta construct!\n"); } CExceptionBeta::~CExceptionBeta() { printf("CExceptionBeta desconstruct!\n"); } CExceptionGroup::CExceptionGroup(int count): m_Alpha(10), m_Beta(20) { if (count < 0 || count > 500) throw std::invalid_argument("Group invalid argument"); m_Count = count; printf("CExceptionGroup construct!\n"); } CExceptionGroup::~CExceptionGroup() { printf("CExceptionGroup desconstruct!\n"); }
// cpp_toys.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "ExceptionConstructor.h" int main() { try { //CExceptionAlpha construct! //CExceptionBeta construct! //CExceptionBeta desconstruct! //CExceptionAlpha desconstruct! //Error occur Beta invalid argument CExceptionGroup group(-1); /*CExceptionAlpha construct! CExceptionBeta construct! CExceptionGroup construct! CExceptionGroup desconstruct! CExceptionBeta desconstruct! CExceptionAlpha desconstruct!*/ CExceptionGroup group(20); } catch(std::invalid_argument &ex) { printf("Error occur %s\n", ex.what()); } return 0; }
二. 析构函数
参照《Effective C++》中条款08:别让异常逃离析构函数。
总结如下:
1. 不要在析构函数中抛出异常!虽然C++并不禁止析构函数抛出异常,但这样会导致程序过早结束或出现不明确的行为。
2. 如果某个操作可能会抛出异常,class应提供一个普通函数(而非析构函数),来执行该操作。目的是给客户一个处理错误的机会。
3. 如果析构函数中异常非抛不可,那就用try catch来将异常吞下,但这样方法并不好,我们提倡有错早些报出来。
本文参考:
1. 《Effective C++》条款08:别让异常逃离析构函数。
2. C++构造函数中抛出的异常
http://blog.csdn.net/deyili/article/details/6332760
3. C++ 构造函数抛出异常会引起内存泄漏吗?:
http://blog.csdn.net/sxf_824/article/details/4926687
4. 构造函数中可不可以抛出异常?析构函数呢?
http://blog.csdn.net/panlong1987/article/details/1835454 5. 是否能在构造函数,析构函数中抛出异常? http://www.cnblogs.com/KevinSong/p/3323372.html
相关文章推荐
- BI中事实表和维度表的定义
- 实现iPhone电子书的分页显示功能(附代码)
- IBM Rational Software Architect 9.0安装
- Python实现复合辛普森求积公式
- 交叉编译libstrophe
- Reader开发(一)电子书分页,翻页效果,字体大小调整和基本功能实现
- Android xml tools 用法 xmlns:tools="http://schemas.android.com/tools"
- netconn_accept返回值为0,OSQCreate出错 lwip uocsii
- [示例]NSPredicate基础-查询数组中负荷条件的子集
- 算法训练 回文数
- Python的MySQLdb模块安装
- 27.Android之ImageView获取图片学习
- maven权威指南学习笔记(一)——简介
- 使用.NET进行高效率互联网敏捷开发的思考和探索【一、概述】
- HPU:1863畅通工程(kruskal)
- 基础背包问题(01,完全,多重)
- <LeetCode OJ> 257. Binary Tree Paths
- VBScript.RegExp 正则表达式excel vba 学习经验
- 【UVa】[227]Puzzle
- C#中HttpWebRequest用Post提交Content-Type: multipart/form-data;