您好,登錄后才能下訂單哦!
構造函數存在的問題:
A、構造函數只提供自動初始化成員變量的機會
B、不能保證初始化邏輯一定成功,如申請系統資源可能失敗
C、執行return語句后構造函數立即結束
構造函數創建的對象可能是半成品對象,半成品對象是合法的對象,但是程序bug的來源之一。因此實際工程開發過程中使用二階構造模式。
由于構造函數存在的潛在問題,實際工程開發中類對象的構造過程如下:
A、資源無關的初始化操作
資源無關的初始化操作一般不會出現異常的情況
B、系統資源相關的操作
與系統資源有關的操作如堆空間申請,文件訪問可能會失敗。
二階構造模式的流程如下:
二階構造模式能夠確保創建的對象都是完整初始化的。由于工程實踐中類對象占用的存儲空間比較大,一般需要分配在堆空間,因此二階構造模式構造對象的方式舍棄了構造函數中將對象分配在棧和全局數據區的情況,只保留創建在堆空間的對象的構造。
二階構造模式示例代碼:
#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;
}
#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;
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。