類的初始化

2021-06-07 10:26:01 字數 1214 閱讀 2706

類的初始化通產有3種型別:使用初始化列表,在建構函式體中賦值,以及使用預設建構函式。

先說前兩種:

初始化列表與在建構函式體中賦值的區別在**呢?主要有兩點:

第一,有的成員不能使用函式體中的「=」初始化。這其實就是初始化與賦值的區別:比如比如const 成員,引用型別,以及沒有定義預設建構函式的類,它們都必須在定義時初始化,而不能賦值,這時候我們的初始化列表就派上用場了。

第二,初始化的順序不同。初始化的順序看起來似乎無關緊要,但是如果乙個資料的初始化依賴於另乙個,就很重要。舉乙個不恰當的例子:

//建構函式

//初始化列表中先試圖先初始化ival1,再用ival1初始化ival2

noname(int i1):ival1(i1),ival2(ival1){}

string *pstring;

//先定義ival2,在定義ival1

int ival2;

int ival1;

如果呼叫noname nm2(2);結果是ival1 = 2,ival2;的值不確定。如果呼叫noname nm2(2);結果是ival1 = 2,ival2;的值不確定。如果呼叫noname nm2(2);結果是ival1 = 2,ival2;的值不確定。這是因為初始化的順序不是初始化列表的順序,而是定義類成員的順序!所以實際上,會用不確定的值初始化ival2,然後再用2初始化ival1.

而使用函式體初始化就避免了這個問題,哪個語句在前,先賦值初始化誰:

noname(int i1)

這樣兩個成員都被初始化為2了。這樣兩個成員都被初始化為2了。這樣兩個成員都被初始化為2了。

說完了前兩種,再看看預設建構函式:

如果定義乙個類時沒有提供初始化式,則使用預設建構函式。但如果這個類哪怕定義了乙個建構函式(即使它缺陷很多),系統也不會使用預設的建構函式。

如果沒有這個類定義建構函式,則會為它合成乙個預設的建構函式,合成規則與變數的初始化規則相同:對於類成員,通過執行它的預設建構函式來初始化;對於內建或者符合型別的成員,因為編譯器應該只對全域性的這種變數初始化,而類的成員不是全域性的,所以這樣就會初始化失敗。

通常情況下,應該為乙個類定義乙個預設建構函式,這樣可以省去定義物件時的許多麻煩,尤其是遇到類的成員是另乙個類型別時,如果這個類型別沒有定義預設建構函式,那麼定義這個類的建構函式時,都要為這個類的那個類型別的成員的建構函式傳遞引數。

類的初始化

類的初始化通產有3種型別 使用初始化列表,在建構函式體中賦值,以及使用預設建構函式。先說前兩種 初始化列表與在建構函式體中賦值的區別在 呢?主要有兩點 第一,有的成員不能使用函式體中的 初始化。這其實就是初始化與賦值的區別 比如比如const 成員,引用型別,以及沒有定義預設建構函式的類,它們都必須...

類的初始化

package 類的初始化 父類的初始化 1 j method 5 2 父類的靜態 塊 1 父類的例項初始化 1 super 最前 2 i test 3 父類的非靜態 塊 4 父類的無參構造 最後 非靜態方法前面其實有乙個預設的物件this this在構造器 或 它表示的是正在建立的物件 因為這裡是...

類的初始化

類的使用順序 類的裝載 鏈結 驗證 準備 解析 初始化 物件例項化 class t implements cloneable static 構造方法是個例項化方法,在 t 被例項化時呼叫 public t string str public static int print string str p...