c 初始化列表

2021-06-10 07:21:50 字數 2766 閱讀 6868

與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。

struct

foo

; //

初始化列表 };

建構函式的兩個執行階段

從概念上來講,建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段

初始化階段

所有類型別(

class type

)的成員都會在初始化階段初始化,即使該成員沒有出現在建構函式的初始化列表中

計算階段

一般用於執行建構函式體內的賦值操作

下面的**定義兩個結構體,其中

test1

有建構函式,拷貝建構函式及賦值運算子,為的是方便檢視結果,

test2

是個測試類,它以

test1

的物件為成員,我們看一下

test2

的建構函式是怎麼樣執行的

struct

test1

test1(const

test1& t1)

// 拷貝建構函式

test1& operator

= (const

test1& t1)

// 賦值運算子

inta ; };

struct

test2 };

呼叫**

test1 t1 ;

test2 t2(t1) ;

輸出 construct test1

construct test1

assignment for test1

解釋一下

第一行輸出對應呼叫**中第一行,構造乙個

test1物件

第二行輸出對應

test2

建構函式中的**,用預設的建構函式初始化物件

test1 //

這就是所謂的初始化階段

第三行輸出對應

test2

的賦值運算子,對

test1

執行賦值操作

// 這就是所謂的計算階段

為什麼使用初始化列表

初始化類的成員有兩種方式,一是使用初始化列表,二是在建構函式體內進行賦值操作

主要是效能問題,對於內建型別,如

int, float

等,使用初始化類表和在建構函式體內初始化差別不是很大,但是對於類型別來說,最好使用初始化列表,為什麼呢?由上面的測試可知,使用初始化列表少了一次呼叫預設建構函式的過程,這對於資料密集型的類來說,是非常高效的。同樣看上面的例子,我們使用初始化列表來實現

test2

的建構函式

struct

test2 }

使用同樣的呼叫**

輸出結果如下

construct test1

copy constructor for test1

第一行輸出對應

呼叫**的第一行

第二行輸出對應

test2

的初始化列表,直接呼叫拷貝建構函式初始化

test1

,省去了呼叫預設建構函式的過程。

所以乙個好的原則是,能使用初始化列表的時候盡量使用初始化列表

哪些東西必須放在初始化列表中

除了效能問題之外,有些時場合初始化列表是不可或缺的,以下幾種情況時必須使用初始化列表

1. 常量成員,因為常量只能初始化不能賦值,所以必須放在初始化列表裡面

2. 引用型別,引用必須在定義的時候初始化,並且不能重新賦值,所以也要寫在初始化列表裡面

3. 沒有預設建構函式的類型別,因為使用初始化列表可以不必呼叫預設建構函式來初始化,而是直接呼叫拷貝建構函式初始化

struct

test1

inti ; };

struct

test2 };

以上**無法通過編譯,因為

test2

的建構函式中

test1 = t1

這一行實際上分成兩步執行

1. 呼叫test1

的預設建構函式來初始化

test1

2. 呼叫test1

的賦值運算子給

test1賦值

但是由於

test1

沒有預設的建構函式,所謂第一步無法執行,故而編譯錯誤。正確的**如下,使用初始化列表代替賦值操作

struct

test2 }

成員變數的初始化順序

成員是按照他們在類中出現的順序進行初始化的,而不是按照他們在初始化列表出現的順序初始化的,看**

struct

foo

; // ok,

先初始化

i,後初始化j

}; 再看下面的**

struct

foo

// i

值未定義 };

這裡i的值是未定義的因為雖然

j在初始化列表裡面出現在

i前面,但是i先於

j定義,所以先初始化i,而

i由j初始化,此時

j尚未初始化,所以導致

i的值未定義。乙個好的習慣是,按照成員定義的順序進行初始化

C 初始化列表

與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。struct foo 初始化列表 ...

C 初始化列表

與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。struct foo 初始化列表 建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段。所有類型別 class type 的成員都會在初始化階...

C 初始化列表

與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。struct foo 初始化列表 ...