一. 构造函数
总结如下:
1. 构造函数中抛出异常,会导致析构函数不能被调用,但对象本身已申请到的内存资源会被系统释放(已申请到资源的内部成员变量会被系统依次逆序调用其析构函数)。
2. 因为析构函数不能被调用,所以可能会造成内存泄露或系统资源未被释放。
3. 构造函数中可以抛出异常,但必须保证在构造函数抛出异常之前,把系统资源释放掉,防止内存泄露。(如何保证???使用auto_ptr???)
试验代码:
1 //ExceptionConstructor.h
2 #pragma once
3 #include <stdexcept>
4
5 class CExceptionConstructor
6 {
7 public:
8 CExceptionConstructor();
9 ~CExceptionConstructor();
10 };
11
12 class CExceptionAlpha
13 {
14 public:
15 explicit CExceptionAlpha(int age) throw(std::invalid_argument);
16 ~CExceptionAlpha();
17
18 private:
19 int m_Age;
20 };
21
22 class CExceptionBeta
23 {
24 public:
25 explicit CExceptionBeta(int height) throw(std::invalid_argument);
26 ~CExceptionBeta();
27
28 private:
29 int m_Height;
30 };
31
32 class CExceptionGroup
33 {
34 public:
35 explicit CExceptionGroup(int count) throw(std::invalid_argument);
36 ~CExceptionGroup();
37
38 private:
39 CExceptionAlpha m_Alpha;
40 CExceptionBeta m_Beta;
41 int m_Count;
42 };
1 //ExceptionConstructor.cpp
2 #include "ExceptionConstructor.h"
3
4 CExceptionConstructor::CExceptionConstructor()
5 {
6 }
7
8
9 CExceptionConstructor::~CExceptionConstructor()
10 {
11 }
12
13 CExceptionAlpha::CExceptionAlpha(int age)
14 {
15 if (age < 0 || age > 200)
16 throw std::invalid_argument("Alpha invalid argument");
17 m_Age = age;
18 printf("CExceptionAlpha construct!\n");
19 }
20
21
22 CExceptionAlpha::~CExceptionAlpha()
23 {
24 printf("CExceptionAlpha desconstruct!\n");
25 }
26
27 CExceptionBeta::CExceptionBeta(int height)
28 {
29 if (height < 5 || height > 500)
30 throw std::invalid_argument("Beta invalid argument");
31 m_Height = height;
32 printf("CExceptionBeta construct!\n");
33 }
34
35
36 CExceptionBeta::~CExceptionBeta()
37 {
38 printf("CExceptionBeta desconstruct!\n");
39 }
40
41 CExceptionGroup::CExceptionGroup(int count):
42 m_Alpha(10), m_Beta(20)
43 {
44 if (count < 0 || count > 500)
45 throw std::invalid_argument("Group invalid argument");
46 m_Count = count;
47 printf("CExceptionGroup construct!\n");
48 }
49
50
51 CExceptionGroup::~CExceptionGroup()
52 {
53 printf("CExceptionGroup desconstruct!\n");
54 }
1 // cpp_toys.cpp : Defines the entry point for the console application.
2 //
3
4 #include "stdafx.h"
5 #include "ExceptionConstructor.h"
6
7 int main()
8 {
9 try
10 {
11 //CExceptionAlpha construct!
12 //CExceptionBeta construct!
13 //CExceptionBeta desconstruct!
14 //CExceptionAlpha desconstruct!
15 //Error occur Beta invalid argument
16 CExceptionGroup group(-1);
17
18 /*CExceptionAlpha construct!
19 CExceptionBeta construct!
20 CExceptionGroup construct!
21 CExceptionGroup desconstruct!
22 CExceptionBeta desconstruct!
23 CExceptionAlpha desconstruct!*/
24 CExceptionGroup group(20);
25 }
26 catch(std::invalid_argument &ex)
27 {
28 printf("Error occur %s\n", ex.what());
29 }
30
31 return 0;
32 }
二. 析构函数
参照《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
