(1)只要建立類型別的新物件都要執行建構函式;
(2)建構函式的名字與類的名字相同,並且不能指定返回型別;
(3)建構函式不能宣告為const,即便是const物件,也是用普通的建構函式來初始化;
(4)建構函式可以使用初始化列表,一般的函式不行。
(1)只有類的建構函式才能使用初始化列表;
(2)初始化列表只出現在建構函式定義的地方,而不出現在其宣告的地方;
初始化列表的形式如下:
class ini_class
;//在類外定義建構函式
ini_class::ini_class() :i1(520), i2(3132)
或者直接在類內定義建構函式:
class ini_class
};
花括號之前,冒號之後的部分,即為建構函式的初始化列表。
初始化的次序是由類中成員定義的次序決定的,而不是由初始化列表中成員出現的次序決定的。
(1)初始化階段,
建構函式初始化列表中被顯式提及的每個成員,都被初始化為給定值;沒有被提及的成員則按照初始化變數的規則來初始化:類型別的成員呼叫預設建構函式來初始化,內建或復合型別(指標、陣列)的成員的初始化依賴於物件的作用域(在什麼地方定義這個類物件的):若處於區域性作用域中,這些成員不被初始化,獲得的值是隨機的;若處於全域性作用域中,則被初始化為0值。
(2)普通的計算階段,
執行建構函式函式體裡的語句。
讓資料成員獲得給定的值,既可以發生在初始化階段,也可以發生在計算階段。
以上面的例子來說就是,由於在初始化列表中提及了i1和i2,所以初始化階段先分別將i1、i2初始化為520和3132,未被提及的str3則呼叫string類的預設建構函式完成初始化。完成之後再執行函式體裡的語句,列印"i am here!".
綜上:類型別的資料成員總是要初始化的,要麼在初始化列表中顯式初始化,要麼就隱式呼叫其預設建構函式,如果不存在預設建構函式,則隱式呼叫預設建構函式失敗。對於這種資料成員就必須在初始化列表中初始化。另外,對於const物件和引用型別的物件,只能初始化,所以const物件成員與引用型別的成員也必須放在初始化列表中初始化,而不能在函式體內賦值。
總結,必須使用初始化列表初始化的資料成員:
(1)資料成員是無缺省建構函式的類物件;
(2)資料成員為const物件;
(3)資料成員為引用型別。
注意:const資料成員是不會被自動初始化的,不管是放在全域性作用域中,還是區域性作用域中。
其實,別說是類的資料成員,就是乙個普通的內建型別的const物件,也不會被預設初始化的,哪怕是在全域性作用域中。編譯未顯式初始化的全域性變數會報錯:
error c2734: 「g_i_love_u」: 如果不是外部的,則必須初始化常量物件。
沒有輸入引數的建構函式即為預設建構函式,包括為所有形參提供預設實參的建構函式。
在定義乙個物件時,如果不提供初始化式,則呼叫的就是預設建構函式。
合成的預設建構函式是指,編譯器為沒有定義任何建構函式的類建立的建構函式。其初始化的規則與初始化變數相同:類型別的成員呼叫預設建構函式來初始化,內建或復合型別(指標、陣列)的成員的初始化依賴於物件的作用域(在什麼地方定義這個類物件的):若處於區域性作用域中,這些成員不被初始化,獲得的值是隨機的;若處於全域性作用域中,則被初始化為0值。
不能使用合成的預設建構函式的情況:
(1)資料成員是無缺省建構函式的類物件,即給類中有自己定義的建構函式,則編譯器不再為其合成預設建構函式;
(2)資料成員為const物件;
(3)資料成員為引用型別。
例如有如下類的定義:
class const_class
;
再定義該類的物件:
const_class i_miss_u;//error c2280: 「const_class::const_class(void)」: 嘗試引用已刪除的函式
推測是合成了預設建構函式後,發現成員中有const物件,又將預設建構函式刪除了。
呼叫預設建構函式的兩種方式:
my_class myobj1;
my_class myobj2 = my_class();
如果程式中,在需要a類型別物件的地方,卻給了其他型別b的物件,而a類型別又有乙個接受b型別形參(只有這乙個形參)的建構函式,則會發生隱式型別轉換,呼叫該建構函式,生成乙個臨時的a型別物件。
這種轉換有時並不是程式的設計者想要的。
為了阻止這種隱式的型別轉換,可以把該建構函式宣告為explicit。被宣告為explicit的建構函式不能再用於隱式型別轉換。
注意explicit只出現在建構函式宣告 的地方,不能出現在它定義的地方。
一般情況下,單形參的建構函式都應該宣告為explicit.
inline: 在成員函式宣告和定義的地方出現皆可,效果相同,兩個地方都出現也可以。
const: 必須在成員函式宣告和定義的地方都出現,因為可以利用建構函式是否為const來過載成員函式。
explicit:只能在建構函式宣告的地方出現,不能在定義的地方出現。
初始化列表:只能在建構函式定義的地方出現,而不能在建構函式宣告的地方出現。
C 學習筆記 建構函式
在建立某個類的物件時,由於對該物件的狀態 資料 不很明確,因此需要對其進行初始化。例如,我們要在長方形中建立乙個物件,或者說新建乙個長方形,那麼我們首先要確定它的長和寬,假如我們無法確定它的長和寬,那麼我們是無法構造出乙個長方形來的。例如,我們要構造乙個長方形,由於建構函式要在建立新物件時使用,因此...
C 學習筆記 拷貝建構函式
拷貝建構函式是一種特殊的建構函式 1 它是建構函式,所以函式名是類名 沒有返回值 2 它是特殊的建構函式 引數形式是固定的 class object 拷貝建構函式的含義 以乙個物件為藍本,來構造另乙個物件。object b object a b 稱作 以b為藍本,建立乙個新的物件a。a是b的乙個拷貝...
C 學習筆記 轉換建構函式
在c中我們知道資料型別之間會進行隱式的型別安全轉換,轉換規則為小型別轉大型別。下面看一些隱式轉換的例子 short s a 合法 unsigned int ui 200 合法 int i 1000 合法 double d i 合法 上面語句都是合法的,要麼同型別賦值,要麼小型別往大型別賦值,當我們在...