C++中類的建構函式
建構函式:
1.定義:是一個特殊的成員函式,名字與類名相同,建立類型別物件時,由編譯器自動呼叫,在物件的生命週期內只且只調用一次,以保證每個資料成員都有一個合適的初值。如:
class Data
{
public:
Data(int year,int month,int day)
{
_year=year;
_month=month;
_day=day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1(2016,9,26);
return 0;
}
上述類中Data()函式即為使用者提供的建構函式,執行後類中資料成員變為:
2.特性:
(1)函式名與類名相同,沒有返回值,可有任意型別的引數;
(2)新物件被建立,建構函式由編譯器自動呼叫;
(3)若使用者沒有提供建構函式,編譯器會提供預設建構函式,一旦使用者提供,編譯器不會在提供預設的建構函式;
(4)建構函式可以過載,實參決定呼叫哪個建構函式;
class Data { public: Data(int year,int month,int day) { _year=year; _month=month; _day=day; } Data(int year) { _year=year; } private: int _year; int _month; int _day; }; int main() { Data d1(2016,9,26); Data d2(2015); return 0; }
(5)無參和帶有預設值的建構函式稱為預設建構函式,並且預設建構函式只能有一個;
(6)建構函式不能用const來修飾。
3.初始化列表
定義:以一個冒號開始,接著是一個以逗號分隔的資料成員列表,每個資料成員後面跟一個放在圓括號中的初始化式。(建構函式由兩階段組成:初始化階段(即初始化列表)、普通計算階段);如:
class Data { public: Data(int year,int month,int day) :_year(year) //初始化列表 ,_month(month) ,_day(day) {} //普通計算階段 private: int _year; int _month; int _day; }; int main() { Data d1(2016,9,26); return 0; }
初始化順序:
(1)每個成員在初始化列表中只能出現一次;
(2)初始化列表僅用於初始化資料成員,並不指定這些資料成員的初始化順序,資料成員在類中定義順序就是在引數列表中的初始化順序;
public:
Data(int year,int month,int day)
:_month(month) //初始化列表
,_day(day)
,_year(year)
{} //普通計算階段
由上程式碼可知初始化列表中資料成員順序可變,但底層初始化資料成員時是按定義順序,如:
Data(int year,int month,int day)
:_year(_month) //初始化列表
,_month(month)
,_day(day)
{} //普通計算階段
_year沒有被初始化。
(3)儘量避免使用成員初始化成員,成員的初始化順序最好和成員的定義順序保持一致;
(4)類資料成員必須在初始化列表初始化的情況:引用資料成員、Const資料成員、類型別成員(該類沒有預設建構函式)。
class Time
{
int _hour;
};
class Data
{
public:
Data(int year=2016,int month=9,int day=26)
:_year(_month) //初始化列表
,_month(month)
,_day(day)
,_time(60)
,ra(_year)
,t()
{} //普通計算階段
private:
int _year;
int _month;
int _day;
int const _time;
int &ra;
Time t;
};
int main()
{
Data d1(2016,9,26);
return 0;
}
4.預設建構函式:
(1)使用者沒有提供建構函式,系統提供預設建構函式時,一般情況編譯器在底層是不會合成預設建構函式,沒有彙編的,特殊情況:若A類包含了B類,A類沒有定義建構函式,B類有預設建構函式,A類會合成預設建構函式,底層會出現彙編;
(2).使用與變數初始化相同的規則來初始化成員,具有類型別的成員通過執行各自的預設建構函式來進行初始化;
(3).內建和複合型別的成員如指標、陣列,只對定義在全域性作用域中的物件初始化,當物件定義在區域性作用域時,內建和符合型別的成員不進行初始化。
5.作用:
(1)構建物件(2)初始化物件
(3)型別轉換如:Date d2 = 2016;(可用explicit關鍵字修飾建構函式,抑制型別隱式轉換)。