初始設定式

文章推薦指數: 80 %
投票人數:10人

如何在C++ 中初始化類別、結構、陣列和基本類型。

... 陣列、 POD 類別、結構及等位都會將其成員初始化為零值。

零初始化在不同時期執行:. 跳到主要內容 已不再支援此瀏覽器。

請升級至MicrosoftEdge,以利用最新功能、安全性更新和技術支援。

下載MicrosoftEdge 其他資訊 目錄 結束焦點模式 語言 閱讀英文 儲存 目錄 閱讀英文 儲存 Twitter LinkedIn Facebook 電子郵件 目錄 初始設定式 發行項 05/04/2022 6位參與者 本文內容 初始設定式指定變數的初始值。

您可以初始化下列內容中的變數: 變數的定義中: inti=3; Pointp1{1,2}; 函式的其中一個參數: set_point(Point{5,6}); 函式的傳回值: Pointget_new_point(intx,inty){return{x,y};} Pointget_new_point(intx,inty){returnPoint{x,y};} 初始設定式可能會有下列格式: 以括號刮住的運算式(或逗號分隔的運算式清單): Pointp1(1,2); 運算式後面接著等號: strings="hello"; 以大括號括住的初始設定式清單。

該清單可能是空的,也可能包含一組清單(如下列範例所示): structPoint{ intx; inty; }; classPointConsumer{ public: voidset_point(Pointp){}; voidset_points(initializer_listmy_list){}; }; intmain(){ PointConsumerpc{}; pc.set_point({}); pc.set_point({3,4}); pc.set_points({{3,4},{5,6}}); } 初始化的類型 初始化分為數種類型,可能會在程式執行的不同時期發生。

不同類型的初始化不會互斥,例如清單初始化可以觸發值初始化,而在其他情況下,則可觸發彙總初始化。

零初始化 零初始化是將變數設為隱含轉換為類型的零值: 數值變數初始化為0(或0.0、0.0000000000等)。

Char變數會初始化為'\0'。

指標會初始化為nullptr。

陣列、POD類別、結構及等位都會將其成員初始化為零值。

零初始化在不同時期執行: 在程式啟動時,對象是具有靜態期間的所有具名變數。

之後可以再次初始化這些變數。

在初始化值期間,對象是純量類型和使用空括號初始化的POD類別類型。

只初始化其成員子集的陣列。

以下舉例說明零初始化: structmy_struct{ inti; charc; }; inti0;//zero-initializedto0 intmain(){ staticfloatf1;//zero-initializedto0.000000000 doubled{};//zero-initializedto0.00000000000000000 int*ptr{};//initializedtonullptr chars_array[3]{'a','b'};//thethirdcharisinitializedto'\0' intint_array[5]={8,9,10};//thefourthandfifthintsareinitializedto0 my_structa_struct{};//i=0,c='\0' } 預設初始化 類別、結構和等位的預設初始化是使用預設建構函式的初始化。

預設建構函式可以使用沒有初始化運算式或new關鍵字來呼叫: MyClassmc1; MyClass*mc3=newMyClass; 如果類別、結構或等位沒有預設建構函式,則編譯器會發出錯誤。

定義純量變數時若未使用初始化運算式,則預設會初始化。

這些變數都具有不定值。

inti1; floatf; charc; 定義陣列時若未使用初始化運算式,則預設會初始化。

預設初始化陣列時,預設會初始化其成員,且其成員具有下列不定值(如下列範例所示): intint_arr[3]; 如果陣列成員沒有預設建構函式,則編譯器會發出錯誤。

常數變數的預設初始化 宣告常數變數時必須搭配使用初始設定式。

如果常數變數是純量類型,則會引發編譯器錯誤,如果是具有預設建構函式的類別類型,則會引發警告: classMyClass{}; intmain(){ //constinti2;//compilererrorC2734:constobjectmustbeinitializedifnotextern //constcharc2;//sameerror constMyClassmc1;//compilererrorC4269:'constautomaticdatainitializedwithcompilergenerateddefaultconstructorproducesunreliableresults } 靜態變數的預設初始化 未使用初始設定式宣告的靜態變數會初始化為0(隱含地轉換為類型)。

classMyClass{ private: intm_int; charm_char; }; intmain(){ staticintint1;//0 staticcharchar1;//'\0' staticboolbool1;//false staticMyClassmc1;//{0,'\0'} } 如需全域靜態物件初始化的詳細資訊,請參閱main函式和命令列引數。

值初始化 在下列情況下,會發生值初始化: 使用空大括號初始設定初始化具名的值。

使用空括號或大括號初始化匿名暫存物件。

物件是以關鍵字加上空白括弧或大括弧初始化new 值初始化會執行下列作業: 對於至少有一個公用建構函式的類別,會呼叫預設建構函式。

對於沒有宣告建構函式的非等位類別,會將該物件初始化為零並呼叫預設建構函式。

對於陣列,會將每個元素初始化為值。

在所有其他情況下,會將變數初始化為零。

classBaseClass{ private: intm_int; }; intmain(){ BaseClassbc{};//classisinitialized BaseClass*bc2=newBaseClass();//classisinitialized,m_intvalueis0 intint_arr[3]{};//valueofallmembersis0 inta{};//valueofais0 doubleb{};//valueofbis0.00000000000000000 } 複製初始化 複製初始化是使用不同的物件初始化同一個物件。

在下列情況下,會發生這類初始化: 使用等號初始化變數 將引數傳遞至函式 從函式傳回物件 擲回或攔截例外狀況 使用等號初始化非靜態資料成員 複製初始化會在彙總初始化期間初始化類別、結構和等位成員。

如需範例,請參閱匯總初始化。

下列程式碼示範數個複製初始化範例: #include usingnamespacestd; classMyClass{ public: MyClass(intmyInt){} voidset_int(intmyInt){m_int=myInt;} intget_int()const{returnm_int;} private: intm_int=7;//copyinitializationofm_int }; classMyException:publicexception{}; intmain(){ inti=5;//copyinitializationofi MyClassmc1{i}; MyClassmc2=mc1;//copyinitializationofmc2frommc1 MyClassmc1.set_int(i);//copyinitializationofparameterfromi inti2=mc2.get_int();//copyinitializationofi2fromreturnvalueofget_int() try{ throwMyException(); } catch(MyExceptionex){//copyinitializationofex cout<v=10;//theconstructorisexplicit;compilererrorC2440:cannotconvertfrom'int'to'std::vector>' regexr="a.*b";//theconstructorisexplicit;sameerror shared_ptrsp=newint(1729);//theconstructorisexplicit;sameerror 在某些情況下,若刪除或無法存取類別的複製建構函式,複製初始化會引發編譯器錯誤。

直接初始化 直接初始化是使用(非空白)大括號或括號的初始化。

直接初始化可以叫用明確建構函式,這點與複製初始化不同。

在下列情況下,會發生這類初始化: 使用非空白大括號或括號初始化變數。

變數是以關鍵字加上非空白大括弧或括弧初始化new 使用初始化變數。

static_cast 在建構函式中,會使用初始設定式清單初始化基底類別和非靜態成員。

在Lambda運算式之所擷取變數的複本中。

下列程式碼示範一些直接初始化範例: classBaseClass{ public: BaseClass(intn):m_int(n){}//m_intisdirectinitialized private: intm_int; }; classDerivedClass:publicBaseClass{ public: //BaseClassandm_chararedirectinitialized DerivedClass(intn,charc):BaseClass(n),m_char(c){} private: charm_char; }; intmain(){ BaseClassbc1(5); DerivedClassdc1{1,'c'}; BaseClass*bc2=newBaseClass(7); BaseClassbc3=static_cast(dc1); inta=1; functionfunc=[a](){returna+1;};//aisdirectinitialized intn=func(); } 清單初始化 使用以大括號括住的初始設定式清單初始化變數時,會發生清單初始化。

在下列情況下,可以使用以大括號括住的初始設定式清單: 初始化變數 類別是使用new關鍵字初始化 從函式傳回物件 將引數傳遞至函式 直接初始化中的其中一個引數 在非靜態資料成員初始設定式中 在建構函式初始設定式清單中 下列程式碼示範一些清單初始化範例: classMyClass{ public: MyClass(intmyInt,charmyChar){} private: intm_int[]{3}; charm_char; }; classMyClassConsumer{ public: voidset_class(MyClassc){} MyClassget_class(){returnMyClass{0,'\0'};} }; structMyStruct{ intmy_int; charmy_char; MyClassmy_class; }; intmain(){ MyClassmc1{1,'a'}; MyClass*mc2=newMyClass{2,'b'}; MyClassmc3={3,'c'}; MyClassConsumermcc; mcc.set_class(MyClass{3,'c'}); mcc.set_class({4,'d'}); MyStructms1{1,'a',{2,'b'}}; } 彙總初始化 彙總初始化是陣列或類別類型(通常是結構或等位)的清單初始化表單,這些陣列或類別類型具有: 非private成員或protected成員 沒有使用者提供的建構函式(明確預設或已刪除的建構函式除外) 沒有基底類別 沒有虛擬成員函式 注意 在VisualStudio2015和更早版本中,不允許匯總具有非靜態成員的大括弧或等於初始化運算式。

此限制已在C++14標準中移除,並在VisualStudio2017中實作。

彙總初始設定式包含以大括號括住的初始化清單(包含或不含等號)(如下列範例所示): #include usingnamespacestd; structMyAggregate{ intmyInt; charmyChar; }; structMyAggregate2{ intmyInt; charmyChar='Z';//member-initializerOKinC++14 }; intmain(){ MyAggregateagg1{1,'c'}; MyAggregate2agg2{2}; cout<



請為這篇文章評分?