既然構造函數初始化列表和構造函數體內賦值均可以對成員變量賦值,那麼兩者有何區別,是否是兩者等效呢?
1、若類的數據成員是靜態的(const)和引用類型,必需用初始化列表
靜態(const)的數據成員只能初始化而不能賦值,一樣引用類型也是隻能夠被初始化,那麼只有用初始化列表。
如: ios
C++代碼函數
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 5 template<class t> 6 class namedptr { 7 public: 8 namedptr(const string& initname, t *initptr); 9 private: 10 const string name; //靜態數據成員的初始化必需用初始化列表 11 t * const ptr; 12 }; 13 14 15 16 template<class t> 17 namedptr<t>::namedptr(const string& initname, t *initptr ) 18 : name(initname), ptr(initptr) 19 {}
因爲 const string name; //靜態數據成員的初始化必需用初始化列表
t * const ptr;
是靜態的,若是用構造函數體內賦值,編譯會出錯。
2、構造函數體內賦值會帶來額外的開銷,效率會低於構造函數初始化列表
上面的例子改一改:
spa
C++代碼code
1 template<class t> 2 class namedptr { 3 public: 4 namedptr(const string& initname, t *initptr); 5 private: 6 string name; //靜態數據成員的初始化必需用初始化列表 7 t * ptr; 8 };
而且用這兩中初始化方法作對比:blog
1 //第一種方法:初始化列表 2 template<class t> 3 namedptr<t>::namedptr(const string& initname, t *initptr ) 4 : name(initname), ptr(initptr) 5 {} 6 7 //第二種方法是在構造函數體內賦值: 8 9 template<class t> 10 namedptr<t>::namedptr(const string& initname, t *initptr) 11 { 12 name = initname; 13 ptr = initptr; 14 }
當用第二種方法初始化數據成員時會兩次對string的成員函數的調用:一次是缺省構造函數,另外一次是賦值。
而用第一種方法(初始化列表)只是一次調用缺省的構造函數,並不會調用賦值函數。會減小沒必要要的開支,當類至關複雜時,就會看出使用初始化列表的好處string