六大默认成员函数中,介绍了构造函数的作用,使用方法。
这份代码中:
class Date
{
public:
Date(int year, int month, int day)//构造函数
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void TestClass()
{
Date d1(2020,10,6);
Date d2(2020, 10, 1);
}
经过上述函数调用之后,虽然对象已经有了初始值,但并不能称之为对象的初始化。在构造函数中的语句只能称作为赋值,函数体中赋值可进行多次,但初始化只有一个。
则对象的初始化是用初始化列表来操作的。
初始化列表: 以冒号开始,接着用每一个逗号分割成员变量列表,每个成员变量后跟一个括号,放入要初始化的变量或表达式。
例:如上述代码初始化
class Date
{
public:
Date(int year, int month, int day)//构造函数
: _year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
void TestClass()
{
Date d1(2020,10,6);
Date d2(2020, 10, 1);
}
初始化列表中注意事项:
- 每个成员变量在初始化列表中只能出现一次。
- 类中有以下成员变量,必须使用初始化列表对成员变量初始化
- 引用成员变量
- const成员变量
- 自定义类型成员(类中没有默认构造函数)
- 尽量使用初始化列表进行初始化。 无论是否使用初始化列表,对于自定义类型的成员变量,一定会优先使用初始化列表初始化。
- 成员变量在类中的声明次序,就是初始化列表中的初始化顺序。与其初始化列表中先后次序无关。
class Date
{
public:
Date(int year, int month, int day)//构造函数
: _year(year)
, _day(day)
, _month(_day)
{}
void Print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
void TestClass()
{
Date d1(2020,10,6);
Date d2(2020, 10, 1);
d1.Print();
}
那么其输出结果是什么呢?
编译器仍是先对month进行初始化,再对day。所以上述month就打印了随机值,因为还未对day进行初始化,就是随机值。
注意:构造函数都有初始化列表,即使用户未写,编译器也会自动补上,依旧会执行初始化列表的部分。