預設構造函數即沒有參數或所有參數都聲明了預設值的構造函數,可以在沒有任何外部資料下初始化對象。當類沒有聲明構造函數,編譯器會提供一個隐式預設構造函數。
借由預設構造函數建立的對象,其成員變量被初始化為固定的或是不确定的值,不能保證類的成員都被正确初始化。當類有一個無意義的預設構造函數,未能将所有部分正确初始化,類的成員函數則必須另外測試成員變量是否是有效的,付出了更多的代碼,是以應盡量避免。
沒有預設構造函數的類必須傳入外部資料來構造,讓人相信這個類的對象會被正确的實作,但也存在使用上的限制。
對象數組
直接聲明對象數組,會調用類的預設構造函數,如果沒有則必須為數組初始化傳參。
Class array[10];//error: no matching function for call to "Class::Class()"
Class array[10] = {{val1, val2, ...}, ...};//correct
但對于堆配置設定的對象數組(
new []
),并不能通過上述方式傳參。
Class * array = new Class[2];//error: no matching function for call to "Class::Class()"
Class * array = new Class(value)[2];//error: 文法錯誤
可以通過(類)指針數組來替代對象數組,并逐個為指針配置設定堆記憶體。對應的,在釋放時也需要逐個調用析構函數。
Class * array[10];
for(auto it : array)
{
it = new Class(value);
}
指針數組的方式使用了額外的記憶體儲存指針,可以使用
placement new
方法為數組配置設定
raw memory
,在記憶體中構造對象。
int size = 10;
void * memory = operator new[](size * sizeof(Class));//類似malloc傳回未處理的堆記憶體塊位址
Class * array = static_cast<Class *>(memory);
for(int i=0; i<size; ++i)
{
new (&array[i]) Class(1, 2);//在已配置設定的位址上構造對象
}
for(int i=0; i<size; ++i)
{
array[i].~Class();
}
memory = static_cast<void *>(array);
operator delete[] (memory);
在模闆容器中使用
pair<int, Class> pa;//error: no matching function for call to 'std::pair<int, Class>::pair()'