【校招面試 之 C++】第1題 為什麽優先使用構造函數的初始化列表
阿新 • • 發佈:2018-07-18
初始化 校招 操作 struct st2 使用 mage div 賦值運算 。
1.首先看一個例子:
#include<iostream> using namespace std; class Test1 { public: Test1() // 無參構造函數 { cout << "Construct Test1" << endl ; } Test1(const Test1& t1) // 拷貝構造函數 { cout << "Copy constructor for Test1" << endl ; this->a = t1.a ; } Test1& operator = (const Test1& t1) // 賦值運算符 { cout << "assignment for Test1" << endl ; this->a = t1.a ; return *this; } private: int a ; }; class Test2 { public: Test1 test1 ; // 情形1:不使用初始化參數列表//Test2(Test1 &t1) //{ // test1 = t1 ; //} // 情形2:使用初始化參數列表 Test2(Test1 &t1):test1(t1){} }; int main(){ Test1 t1; Test2 t2(t1); system("pause"); return 0; }
情形1輸出:
情形2輸出:
第二種情況輸出對應Test2的初始化列表,直接調用拷貝構造函數初始化test1,省去了調用默認構造函數的過程。所以一個好的原則是,能使用初始化列表的時候盡量使用初始化列表。提高了性能。
2. 除了性能問題之外,有些時場合初始化列表是不可或缺的,以下幾種情況時必須使用初始化列表
- 常量成員,因為常量只能初始化不能賦值,所以必須放在初始化列表裏面
- 引用類型,引用必須在定義的時候初始化,並且不能重新賦值,所以也要寫在初始化列表裏面
- 沒有默認構造函數的類類型,因為使用初始化列表可以不必調用默認構造函數來初始化,而是直接調用拷貝構造函數初始化。
對於沒有默認構造函數的類,我們看一個例子。
struct Test1 { Test1(int a):i(a){} int i ; }; struct Test2 { Test1 test1 ; Test2(Test1 &t1) { test1 = t1 ; } };
以上代碼無法通過編譯,因為Test2類中Test1 test1;需要調用默認的構造函數,但是Test1類沒有無參的構造函數,但是由於Test1沒有默認的構造函數,故而編譯錯誤。正確的代碼如下,使用初始化列表代替賦值操作。
struct Test2 { Test1 test1 ; Test2(Test1 &t1):test1(t1){} }
成員變量的初始化順序
成員是按照他們在類中出現的順序進行初始化的,而不是按照他們在初始化列表出現的順序初始化的,看代碼。
struct foo { int i ; int j ; foo(int x):i(x), j(i){}; // ok, 先初始化i,後初始化j };
【校招面試 之 C++】第1題 為什麽優先使用構造函數的初始化列表