初始化列表:
一一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或表达式。
#include <iostream>
using namespace std;
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{
}
private:
int _year;
int _month;
int _day;
};
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称作为类对象成员的初始化,构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
【初始化列表是每个成员定义的地方,不管你写不写,每个成员都要走初始化列表】
类中的以下成员,必须放在初始化列表中进行初始化(定义时必须初始化):
1.、引用成员变量
2.const成员变量
3.自定义类型成员(该类默认没有构造函数)
特点:
1.成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class A
{
public:
A(int a)
:_a1(a)
,_a2(_a1)
{}
void Print()
{
cout << _a1 << " " << _a2 << endl;
}
private:
int _a2;
int _a1;
};
int main()
{
A aa(1);
aa.Print();
return 0;
}
这里aa.Print()输出的并不是 1 1
而是_a1 = 1, _a2为随机值
原因:成员变量的初始化顺序是根据其声明的顺序,如下:
所以先初始化_a2,因为此时_a1还未被初始化,所以_a2就会被初始化为随机值。
2.对于内置类型的成员变量,如果不写在初始化列表,就会初始化为随机值。如果是自定义类型,不写在初始化列表中,则会去调用自身的默认构造。(如下)
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class A
{
public:
A(int a = 10)
:_a(a)
{}
private:
int _a;
};
class Date
{
public:
Date(int year, int month, int day)
: _year(year)
, _month(month)
, _day(day)
{}
private:
A _a;
int _year;
int _month;
int _day;
int i;
};
int main()
{
Date d1(2007, 7, 20);
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
类中定义成员变量给的缺省值其实是给的初始化列表
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
class Date
{
public:
Date(int year, int month)
: _year(year)
, _month(month)
{}
private:
int _year;
int _month;
int _day = 20;
};
int main()
{
Date d1(2007, 7);
return 0;
}
如果初始化列表没有显示给值,就用这个缺省值。
如果显示的给了,就不用这个缺省值了。