C++--二階構造的實現

`
#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;
}

1.構造函數與半成品對象

2.二階構造

3.小結

1.構造函數與半成品對象
關於構造函數:

類的構造函數用於對象的初始化
構造函數與類同名並且沒有返回值
構造函數在對象定義時自動被調用
問題:

如何判斷構造函數的執行結果?
在構造函數中執行return語句會發生什麼?
構造函數執行結束是否意味着對象構造成功?
(沒有辦法判斷構造函數的執行結果,構造函數執行結束不意味着對象構造成功)
用一個狀態來表示對象是否構造成功:

#include <stdio.h>

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;
}

};

int main()
{
Test t1(1, 2);

if( t1.status() )
{
    printf("t1.mi = %d\n", t1.getI());
    printf("t1.mj = %d\n", t1.getJ());
}

return 0;

}
輸出結果爲空。

構造函數:

只提供自動初始化成員變量的機會
不能保證初始化邏輯一定成功
執行return語句後構造函數立即結束
構造函數能決定的只是對象的初始狀態,而不是對象的誕生!!

半成品對象的概念:

初始化操作不能按照預期完成而得到的對象
半成品對象是合法的C++對象,也是Bug的重要來源
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;

}
運行結果爲:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
obj = 0xd4f010
若是二階構造失敗了呢?

#include <stdio.h>

class TwoPhaseCons
{
private:
TwoPhaseCons() // 第一階段構造函數
{
}
bool construct() // 第二階段構造函數
{
return false;
}
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;

}
運行結果爲:

[root@bogon Desktop]# g++ test.cpp
[root@bogon Desktop]# ./a.out
obj = (nil)
會返回一個空。

使用二階構造模式後,對象只能在堆空間上創建,不能在棧上產生了。這恰恰是工程裏面最重要的一個決定,因爲在工程中,對象往往是比較巨大的,不適合放在棧空間當中,都應該放到堆空間裏面去。

3.小結
構造函數只能決定對象的初始化狀態
構造函數中初始化操作的失敗不影響對象的誕生
初始化不完全的半成品對象是Bug的重要來源
二階構造人爲的將初始化過程分爲兩部分
二階構造能夠確保創建的對象都是完整初始化的


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章