1.定義
構(gòu)造函數(shù)除了有名字里初,參數(shù)列表和函數(shù)體之外掂铐,還可以有初始化列表芒澜,初始化列表以冒號(hào)開頭,后跟一系列以逗號(hào)分隔的初始化字段
class foo
{
public:
foo(string s, int i) :name(s), id(i) {}; // 初始化列表
private:
string name; int id;
};
#include<iostream>
using namespace std;
class Test1
{
public:
Test1() // 無參構(gòu)造函數(shù)
{
cout << "Construct Test1" << endl;
}
Test1(const Test1& t1) // 拷貝構(gòu)造函數(shù)
{
cout << "Copy constructor for Test1" << endl;
this->a = t1.a;
}
Test1& operator = (const Test1& t1) // 賦值運(yùn)算符
{
cout << "assignment for Test1" << endl;
this->a = t1.a;
return *this;
}
int a;
};
class Test2
{
public:
Test1 test1;
Test2(Test1& t1)
{
test1 = t1;
}
};
int main()
{
Test1 t1;
//Test1 t2(t1);
Test2 t2(t1);
}
#輸出結(jié)果
1.0
Construct Test1
Construct Test1
assignment for Test1
2.0
Construct Test1
Copy constructor for Test1
結(jié)果分析
第一行輸出對(duì)應(yīng)調(diào)用代碼中第一行卧须,構(gòu)造一個(gè)Test1對(duì)象
第二行輸出對(duì)應(yīng)Test2構(gòu)造函數(shù)中的代碼另绩,用默認(rèn)的構(gòu)造函數(shù)初始化對(duì)象test1 // 這就是所謂的初始化階段
第三行輸出對(duì)應(yīng)Test2的賦值運(yùn)算符儒陨,對(duì)test1執(zhí)行賦值操作 這就是所謂的計(jì)算階段
2.為何使用初始化列表
- 對(duì)一般的內(nèi)置類型來說,使用初始化類的成員有兩種方式笋籽,一是使用初始化列表蹦漠,二是在構(gòu)造函數(shù)體內(nèi)進(jìn)行賦值操作。
- 主要是性能問題干签,對(duì)于內(nèi)置類型津辩,如int, float等,使用初始化類表和在構(gòu)造函數(shù)體內(nèi)初始化差別不是很大
- 但是對(duì)于類類型來說容劳,最好使用初始化列表。由下面的測(cè)試可知闸度,使用初始化列表少了一次調(diào)用默認(rèn)構(gòu)造函數(shù)的過程竭贩,這對(duì)于數(shù)據(jù)密集型的類來說,是非常高效的莺禁。同樣看上面的例子留量,我們使用初始化列表來實(shí)現(xiàn)Test2的構(gòu)造函數(shù)
第一行輸出對(duì)應(yīng)調(diào)用代碼的第一行。
第二行輸出對(duì)應(yīng)Test2的初始化列表哟冬,直接調(diào)用拷貝構(gòu)造函數(shù)初始化test1楼熄,省去了調(diào)用默認(rèn)構(gòu)造函數(shù)的過程。
所以一個(gè)好的原則是浩峡,能使用初始化列表的時(shí)候盡量使用初始化列表
3.什么情況下必須調(diào)用初始化列表
1.常量成員可岂,因?yàn)槌A恐荒艹跏蓟荒苜x值,所以必須放在初始化列表里面
2.引用類型翰灾,引用必須在定義的時(shí)候初始化缕粹,并且不能重新賦值,所以也要寫在初始化列表里面
3.沒有默認(rèn)構(gòu)造函數(shù)的類類型纸淮,因?yàn)槭褂贸跏蓟斜砜梢圆槐卣{(diào)用默認(rèn)構(gòu)造函數(shù)來初始化平斩,而是直接調(diào)用拷貝構(gòu)造函數(shù)初始化
class Test1
{
public:
Test1(int a):i(a){}
int i;
};
class Test2
{
public:
Test1 test1 ;
Test2(Test1 &t1)
{test1 = t1 ;} //會(huì)出錯(cuò), 調(diào)用Test1的默認(rèn)構(gòu)造函數(shù)來初始化test1咽块,由于Test1沒有默認(rèn)的構(gòu)造函數(shù)
};
Test2(int x):test1(x){}