構造函數和析構函數中得異常處理

一. 構造函數html

總結以下:app

1. 構造函數中拋出異常,會致使析構函數不能被調用,但對象自己已申請到的內存資源會被系統釋放(已申請到資源的內部成員變量會被系統依次逆序調用其析構函數)。函數

2. 由於析構函數不能被調用,因此可能會形成內存泄露或系統資源未被釋放。spa

3. 構造函數中能夠拋出異常,但必須保證在構造函數拋出異常以前,把系統資源釋放掉,防止內存泄露。(如何保證???使用auto_ptr???).net

 

試驗代碼:code

 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 }

 


二. 析構函數htm

參照《Effective C++》中條款08:別讓異常逃離析構函數。對象

  總結以下:blog

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/18354545. 是否能在構造函數,析構函數中拋出異常? http://www.cnblogs.com/KevinSong/p/3323372.html

相關文章
相關標籤/搜索