C 學習筆記32 建構函式

2021-07-08 15:25:47 字數 2701 閱讀 8880

(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 合法 上面語句都是合法的,要麼同型別賦值,要麼小型別往大型別賦值,當我們在...