C++的初始化列表:
在C++中,有的構造函數除了有名字,參數列表和函數體之外,還可以有初始化列表。初始化列表以一個冒號開始,緊接着就是以逗號分隔的數據成員列表,每個數據成員後面跟一個放在括號中的初始化式。
class A
{
private:
int i;
double j;
public:
A():i(5),j(5.0){}
A()
{
i=5;
j=5.0;
}
};
上述兩個構造函數的功能是一樣的,一個可以由另一個代替,當然是不能同時出現的,這裏只是舉一個例子。
何時使用初始化列表:
- 常量成員
- 引用類型
class A
{
private:
int x,℞
const double pi;
public:
A(int i):x(i),rx(x),pi(3.14)
{}
void display()
{cout<<"x="<<x<<"rx="<<rx<<"pi="<<pi<<endl;}
};
上面的代碼中,pi 爲常量, rx 爲引用類型。
- 沒有默認構造函數的類類型
class Test1
{
public:
Test1(int a):i(a){}
int i;
};
class Test2
{
public:
Test1 test1 ;
Test2(Test1 &t1){test1 = t1 ;}
};
因爲Test1 沒有默認的構造函數,上述代碼會出現報錯。
應該必須用初始化列表,正確的代碼如下:
class Test1
{
public:
Test1(int a):i(a){}
int i;
};
class Test2
{
public:
Test1 test1 ;
Test2(int x):test1(x){}
};
如果沒有定義任何構造函數 ,C++編譯器會自動創建一個默認構造函數 。 如果已經定義了一個構造函數,編譯器不會自動創建默認構造函數,只能顯式調用該構造函數。
初始化順序:
按照數據成員在類中的聲明順序進行初始化,與初始化成員列表中出現的順序無關。
class Test
{
private:
int i,j;
public:
Test(int x):j(x),i(j){}//i的值未定義
};
上述代碼中,在定義的時候,i 比 j 提前定義,所以也應該提前初始化。
下面的纔是正確的:
{
private:
int i,j;
public:
List(int x):i(x),j(i){};
};
總結一下初始化列表:
1 因爲初始化列表中無法直接初始化基類的數據成員,所以你需要在列表中指定基類的構造函數,如果不指定,編譯器則會調用基類的默認構造函數。
2 推薦使用初始化列表,它會比在函數體內初始化派生類成員更快,因爲在分配內存後,在函數體內又多進行了一次賦值操作。
3 初始化列表並不能指定初始化的順序,正確的順序是,首先初始化基類,其次根據派生類成員聲明次序依次初始化。