既然建構函式初始化列表和建構函式體內賦值都可以對成員變數賦值,那麼二者有何區別,是不是二者等效呢?
建構函式可以分兩個階段進行:(1)初始化階段;(2)普通計算階段。計算階段也就是由函式體內所有的語句組成。不管成員是否在建構函式初始化列表中顯式初始化,類的資料成員初始化總是在初始化階段進行,初始化階段先於計算階段。建構函式初始化列表是對類的成員做初始化,而在建構函式體內只是對類的資料成員進行了一次賦值操作。
建構函式初始化列表只是指定了成員的初始值,並沒有指定初始化順序,那麼成員初始化順序又是怎樣的呢?成員的初始化順序就是定義成員的順序,第乙個定義的成員首先被初始化,然後是第二個等等。
一、若類的資料成員是靜態的(const)和引用型別,必需用初始化列表
靜態(const)的資料成員只能初始化而不能賦值,同樣引用型別也是只可以被初始化,那麼只有用初始化列表。
如: c++**
#include
#include
using
namespace std;
template
class namedptr ;
template
namedptr::namedptr(const string& initname, t *initptr )
: name(initname), ptr(initptr)
{}
//第二種方法是在建構函式體內賦值:
//template
//namedptr::namedptr(const string& initname, t *initptr)
//int main()
由於 const string name; //靜態資料成員的初始化必需用初始化列表
t * const ptr;
是靜態的,如果用建構函式體內賦值,編譯會出錯。
二、建構函式體內賦值會帶來額外的開銷,效率會低於建構函式初始化列表
上面的例子改一改:
c++**
template
class namedptr ;
並且用這兩中初始化方法做對比:
c++**
//第一種方法:初始化列表
template
namedptr::namedptr(const string& initname, t *initptr )
: name(initname), ptr(initptr)
{}
//第二種方法是在建構函式體內賦值:
template
namedptr::namedptr(const string& initname, t *initptr)
當用第二種方法初始化資料成員時會兩次對string的成員函式的呼叫:一次是預設建構函式,另一次是賦值。
而用第一種方法(初始化列表)只是一次呼叫預設的建構函式,並不會呼叫賦值函式。會減少不必要的開支,當類相當複雜時,就會看出使用初始化列表的好處。
hzhsan注:區別不只上面這些!!!
C 建構函式與初始化列表
c 引入建構函式的目的在於對變數的初始化做出強制,因為人們發現,程式的錯誤,很大程度上來說,都是由變數沒有初始化造成的。因此,一種很好的程式設計習慣就是,在定義變數的時候直接初始化。而在c 中,在變數定義時,系統會自動呼叫變數的建構函式對變數進行初始化。只要將相應的初始化 放在建構函式中,就能夠保證...
C 建構函式 ,初始化列表
c 中的類的建構函式 1.如果類中沒有定義建構函式,編譯器將生成乙個預設建構函式,這個預設建構函式會呼叫類中所有成員的預設建構函式,但不會對如int,double的基本資料型別做初始化 2.類中可以定義多個建構函式,但每個建構函式應該有不同的引數實現 3.預設建構函式必須定義的情況,當需要定義乙個物...
C 建構函式初始化列表
從概念上講,可以認為建構函式分兩個階段進行 1.初始化階段 2.普通的計算階段。計算階段由建構函式函式體中的所有語句組成 不管成員是否在建構函式初始化列表中顯示初始化,類型別的資料成員總是在初始化階段初始化。初始化發生在計算階段的開始之前。建議 使用建構函式初始化列表 注 必須對任何const或引用...