見《c++ primer》p387
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c++中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的**都以struct來演示。
struct建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段。foo ; //
初始化列表
};
初始化順序:
首先,呼叫基類的建構函式,如果基類構造函式呼叫在初始化列表中存在,則就按照初始化列表中的呼叫形式做;否則,就呼叫基類相應的無引數建構函式。緊接著,所有類型別(class type)的成員都會在初始化階段初始化,即使該成員沒有出現在建構函式的初始化列表中;如果類型別的成員沒有出現在初始化列表中,則會呼叫該類型別成員的預設建構函式來初始化它。
一般用於執行建構函式體內的賦值操作。
初始化類的成員有兩種方式,一是使用初始化列表,二是在建構函式體內進行賦值操作。使用初始化列表主要是基於效能問題,對於內建型別,如int, float等,使用初始化類表和在建構函式體內初始化差別不是很大----因為內建型別的成員在初始化階段不進行隱式初始化,但是對於類型別來說,最好使用初始化列表,為什麼呢?因為對於類型別而言,在初始化階段已經呼叫預設建構函式初始化過一次了,如果再在建構函式裡呼叫賦值函式再初始化一次就相當於初始化兩次了。
除了效能問題之外,有些時場合初始化列表是不可或缺的,以下幾種情況時必須使用初始化列表
對於沒有預設建構函式的類,我們看乙個例子。
struct以上**無法通過編譯,因為test1沒有預設的建構函式,故而編譯錯誤。正確的**如下,使用初始化列表代替賦值操作。test1
inti ;
};struct
test2
};
struct成員是按照他們在類中出現的順序進行初始化的,而不是按照他們在初始化列表出現的順序初始化的,看**。test2
}
struct再看下面的**foo; //
ok, 先初始化i,後初始化j
};
struct這裡i的值是未定義的因為雖然j在初始化列表裡面出現在i前面,但是i先於j定義,所以先初始化i,但i由j初始化,此時j尚未初始化,所以導致i的值未定義。所以,乙個好的習慣是,按照成員定義的順序進行初始化。foo //
i值未定義
};
例子:const
常量需要在宣告的時候即初始化。因此需要在變數建立的時候進行初始化。一般採用在建構函式的初始化列表中進行。
class ca ;
ca::ca():max(100)
reference
引用型變數:
引用型變數和
const
變數類似。需要在建立的時候即進行初始化。也是在初始化列表中進行。但需要注意用
reference
型別。
class ca ;
ca::ca():counter(&init)
c 初始化列表
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。struct foo 初始化列表 建構函式的兩個執行階段 從概念上來講,建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段 初始化階段 所有...
C 初始化列表
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。在c 中,struct和class的唯一區別是預設的克訪問性不同,而這裡我們不考慮訪問性的問題,所以下面的 都以struct來演示。struct foo 初始化列表 ...
C 初始化列表
與其他函式不同,建構函式除了有名字,引數列表和函式體之外,還可以有初始化列表,初始化列表以冒號開頭,後跟一系列以逗號分隔的初始化字段。struct foo 初始化列表 建構函式的執行可以分成兩個階段,初始化階段和計算階段,初始化階段先於計算階段。所有類型別 class type 的成員都會在初始化階...