初始化列表 知多少

C++的初始化列表:

在C++中,有的構造函數除了有名字,參數列表和函數體之外,還可以有初始化列表。初始化列表以一個冒號開始,緊接着就是以逗號分隔的數據成員列表,每個數據成員後面跟一個放在括號中的初始化式。

class A
{
private:
    int i;
    double j;
public:
    A():i(5),j(5.0){}
    A()
    {
        i=5;
        j=5.0;
    }
};

上述兩個構造函數的功能是一樣的,一個可以由另一個代替,當然是不能同時出現的,這裏只是舉一個例子。

何時使用初始化列表:

  1. 常量成員
  2. 引用類型
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 爲引用類型。

  1. 沒有默認構造函數的類類型
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 初始化列表並不能指定初始化的順序,正確的順序是,首先初始化基類,其次根據派生類成員聲明次序依次初始化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章