1. 程式人生 > >C++語言學習(六)——二階構造模式

C++語言學習(六)——二階構造模式

工程 ESS 語句 argc 流程 失敗 ostream 分享圖片 半成品對象

C++語言學習(六)——二階構造模式

一、構造函數的問題

構造函數存在的問題:
A、構造函數只提供自動初始化成員變量的機會
B、不能保證初始化邏輯一定成功,如申請系統資源可能失敗
C、執行return語句後構造函數立即結束
構造函數創建的對象可能是半成品對象,半成品對象是合法的對象,但是程序bug的來源之一。因此實際工程開發過程中使用二階構造模式。

二、二階構造模式

1、二階構造模式簡介

由於構造函數存在的潛在問題,實際工程開發中類對象的構造過程如下:
A、資源無關的初始化操作
資源無關的初始化操作一般不會出現異常的情況
B、系統資源相關的操作
與系統資源有關的操作如堆空間申請,文件訪問可能會失敗。
二階構造模式的流程如下:

技術分享圖片
二階構造模式能夠確保創建的對象都是完整初始化的。由於工程實踐中類對象占用的存儲空間比較大,一般需要分配在堆空間,因此二階構造模式構造對象的方式舍棄了構造函數中將對象分配在棧和全局數據區的情況,只保留創建在堆空間的對象的構造。

2、二階構造模式示例

二階構造模式示例代碼:

#include <stdio.h>

class TwoPhaseCons 
{
private:
    TwoPhaseCons() // 第一階段構造函數
    {   
    }
    bool construct() // 第二階段構造函數
    { 
        return true; 
    }
public:
    static TwoPhaseCons* NewInstance(); // 對象創建函數
};

TwoPhaseCons* TwoPhaseCons::NewInstance() 
{
    TwoPhaseCons* ret = new TwoPhaseCons();

    // 若第二階段構造失敗,返回 NULL    
    if( !(ret && ret->construct()) ) 
    {
        delete ret;
        ret = NULL;
    }

    return ret;
}

int main()
{
    TwoPhaseCons* obj = TwoPhaseCons::NewInstance();

    printf("obj = %p\n", obj);

    delete obj;

    return 0;
}

3、二階構造函數應用

#include <iostream>

using namespace std;

class IntArray
{
private:
    IntArray(int len)
    {
        m_length = len;
    }
    IntArray(const IntArray& obj);

    bool construct()
    {
        bool ret = true;
        m_pointer = new int[m_length];
        if( m_pointer )
        {
            for(int i=0; i<m_length; i++)
            {
                m_pointer[i] = 0;
            }
        }
        else
        {
            ret = false;
        }
        return ret;
    }
public:
    static IntArray* NewInstance(int length)
    {
        IntArray* ret = new IntArray(length);
        //如果資源申請失敗
        if( !(ret && ret->construct()) )
        {
            delete ret;
            ret = 0;
        }
        return ret;
    }
    int length()
    {
        return m_length;
    }
    bool get(int index, int& value)
    {
        bool ret = (0 <= index) && (index < length());
        if( ret )
        {
            value = m_pointer[index];
        }
        return ret;
    }
    bool set(int index ,int value)
    {
        bool ret = (0 <= index) && (index < length());
        if( ret )
        {
            m_pointer[index] = value;
        }
        return ret;
    }
    ~IntArray()
    {
        delete [] m_pointer;
    }
private:
    int m_length;
    int* m_pointer;
};

int main(int argc, char *argv[])
{
    IntArray* array = IntArray::NewInstance(5);
    cout << array->length() << endl;
    return 0;
}

C++語言學習(六)——二階構造模式