构造函数和析构函数中得异常处理


一. 构造函数

总结如下:

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

 


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
  © 2014-2022 ITdaan.com 联系我们: