18、不一樣的C++系列--二階構造模式

構造函數回顧


  • 關於構造函數的回顧
    • 類的構造函數用於對象的初始化
    • 構造函數與類同名並且沒有返回值
    • 構造函數在對象定義時自動被調用
但是有沒有發現,還是存在一些問題?
1、如何判斷構造函數的執行結果呢?
2、在構造函數中執行return 語句會發生什麼?
3、構造函數執行結束是否意味着對象構造成功?

就像這樣:

class Test
{
    int mi;
    int mj;
    bool mStatus;
public:
    Test(int i, int j) : mStatus(false)
    {
        mi = i;

        //這裏直接返回,會造成其他的成員變量沒有賦值成功
        return;

        mj = j;

        mStatus = true;
    }
    int getI()
    {
        return mi;
    }
    int getJ()
    {
        return mj;
    }
    int status()
    {
        return mStatus;
    }
};

構造函數的特性:

  • 只提供自動初始化成員變量的機會
  • 不能保證初始化邏輯一定成功
  • 執行return 語句後構造函數立即結束

所以當初始化操作不能按照預期完成而得到的對象稱爲半成品對象,它是合法的C++對象,也是BUG的重要來源。

二階構造


此時就引出來另外一個概念: 二階構造

  • 工程開發中的構造過程可分爲:
    • 資源無關的初始化操作
      • 不可能出現異常情況的操作
    • 需要使用系統資源的操作
      • 可能出現異常,如:內存申請,訪問文件
Created with Raphaël 2.1.0創建對象資源無關初始操作系統資源申請操作資源申請成功?返回對象結束刪除半成品對象返回NULLyesno
  • 二階構造示例
class TwoPhaseCons{
    private:

        //第一階段構造函數
        TwoPhaseCons(){

        }

        //第二階段構造函數
        bool construce(){
            return true;
        }
    public:

        //對象創建函數
        static TwoPhaseCons* NewInstance();
};

TwoPhaseCons* TwoPhaseCons:: NewInstance(){

    TwoPhaseCons* ret = new TwoPhaseCons();

    if(!(ret && ret->construct())){

        delete ret;

        ret = NULL;
    }

    return ret;
}

小結


  • 構造函數只能決定對象的初始化狀態
  • 構造函數中初始化操作的失敗不影響對象的誕生
  • 初始化不完全的半成品對象是bug的重要來源
  • 二階構造人爲的將初始化過程分爲兩部分
  • 二階構造能夠確保創建的對象都是完成初始化的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章