构造函数:
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关键字修饰构造函数,抑制类型隐式转换)。