1. 程式人生 > >二階構造模式

二階構造模式

style 一個 truct array 完整 pre .get 被調用 private

模式:方法。設計模式,就是設計方法。前人證明了的行之有效的方法。

構造函數:

1.關於構造函數

-類的構造函數用於對象的初始化。

-構造函數與類同名並且沒有返回值。

-構造函數在對象定義時自動被調用。

問題:

1.如何判斷構造函數的執行結果?

2.在構造函數中執行return語句會發生什麽?

3.構造函數執行結束是否意味對象構造成功?

編程實驗:異常的構造函數.cpp

 1 #include <stdio.h>
 2 
 3 class Test
 4 {
 5     int mi;
 6     int mj;
 7     bool mStatus;
 8 public
: 9 Test(int i, int j) : mStatus(false) 10 { 11 mi = i; 12 13 return; 14 15 mj = j; 16 17 mStatus = true; 18 } 19 int getI() 20 { 21 return mi; 22 } 23 int getJ() 24 { 25 return mj; 26 } 27 int
status() 28 { 29 return mStatus; 30 } 31 }; 32 33 int main() 34 { 35 Test t1(1, 2); 36 37 if( t1.status() ) 38 { 39 printf("t1.mi = %d\n", t1.getI()); 40 printf("t1.mj = %d\n", t1.getJ()); 41 42 } 43 44 return 0; 45 }

你需要知道的真相:

-構造函數

1.只提供自動初始化變量的機會;

2.不能保證初始化邏輯一定成功;

3.執行return 語句後構造函數立即結束。

構造函數能決定的只是對象的初始狀態,而不是對象的誕生。

半成品對象:

-初始化操作不能按照預期完成而得到的對象;

-半成品對象是合法的C++對象,也是BUG的重要來源。

半成品對象的危害

IntArray.cpp

 1 #include "IntArray.h"
 2 
 3 IntArray::IntArray(int len)
 4 {
 5     m_length = len;
 6 }
 7 
 8 bool IntArray::construct()
 9 {
10     bool ret = true;
11     
12     m_pointer = new int[m_length];
13     
14     if( m_pointer )
15     {
16         for(int i=0; i<m_length; i++)
17         {
18             m_pointer[i] = 0;
19         }
20     }
21     else
22     {
23         ret = false;
24     }
25     
26     return ret;
27 }
28 
29 IntArray* IntArray::NewInstance(int length) 
30 {
31     IntArray* ret = new IntArray(length);
32     
33     if( !(ret && ret->construct()) ) 
34     {
35         delete ret;
36         ret = 0;
37     }
38         
39     return ret;
40 }
41 
42 int IntArray::length()
43 {
44     return m_length;
45 }
46 
47 bool IntArray::get(int index, int& value)
48 {
49     bool ret = (0 <= index) && (index < length());
50     
51     if( ret )
52     {
53         value = m_pointer[index];
54     }
55     
56     return ret;
57 }
58 
59 bool IntArray::set(int index, int value)
60 {
61     bool ret = (0 <= index) && (index < length());
62     
63     if( ret )
64     {
65         m_pointer[index] = value;
66     }
67     
68     return ret;
69 }
70 
71 IntArray::~IntArray()
72 {
73     delete[]m_pointer;
74 }

針對上面的問題,我們如何使用一個行之有效的辦法解決?

二階構造:

-工程開發中的構造函數過程可分為

1.資源無關的初始化操作

  -不可能出現異常情況的操作

2.需要使用系統資源的操作

  -可能出現異常情況,如:內存申請,訪問文件。

步驟:

創建對象——》資源無關初始操作——》資源相關初始操作——》資源申請成功——》true——》返回對象

代碼:

 1 #include <stdio.h>
 2 
 3 class TwoPhaseCons 
 4 {
 5 private:
 6     TwoPhaseCons() // 第一階段構造函數
 7     {   
 8     }
 9     bool construct() // 第二階段構造函數
10     { 
11         return true; 
12     }
13 public:
14     static TwoPhaseCons* NewInstance(); // 對象創建函數
15 };
16 
17 TwoPhaseCons* TwoPhaseCons::NewInstance() 
18 {
19     TwoPhaseCons* ret = new TwoPhaseCons();
20 
21     // 若第二階段構造失敗,返回 NULL    
22     if( !(ret && ret->construct()) ) 
23     {
24         delete ret;
25         ret = NULL;
26     }
27         
28     return ret;
29 }
30 
31 
32 int main()
33 {
34     TwoPhaseCons* obj = TwoPhaseCons::NewInstance();
35     
36     printf("obj = %p\n", obj);
37 
38     delete obj;
39     
40     return 0;
41 }

小結:

-構造函數只能決定對象的初始化狀態;

-構造函數中初始化操作的失敗不影響對象的產生;

-初始化不完全的半成品對象是Bug的重要來源;

-二階構造人為的將初始化過程分為兩部分;

-二階構造能夠確保創建的對象都是完整初始化的。

二階構造模式