·1.初始化列表是什么
·2.使用初始化列表更高效,为什么?
·3.哪些成成员变量必须放在初始化列表里?
·4.成员变量按声明顺序初始化,而不是初始化列表。
·5.声明和定义的区别
·6.那些类必须自己写构造函数
类的成员变量有俩种初始化方式:1.初始化列表。2.构造函数体内进行赋值。
之前使用的初始化方式是第二种,那么第一种方式初始化列表是什么呢?
1.初始化列表是什么?初始化列表是以一个冒号开始,接着一个逗号分隔数据列表,每个数据成员都放入一个括号中进行初始化。
2.使用初始化列表更高效,为什么呢?尽量使用初始化列表进行初始化,因为这样子更加高效,为什么更加高效呢?先写一段代码。
class Time
{
public:
Time()
{
cout<<"Time()"<<endl;
_hour = 0;
_minute = 0;
_second = 0;
}
Time(const Time& t)
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
//【1】
Date(int year,int month,int day,const Time& t)
{
cout<<"Date()非初始化列表"<<endl;
_year = year;
_month = month;
_day = day;
_t = t;
}
//【2】
Date(int year,int month,int day,const Time& t)
:_year(year)
,_month(month)
,_day(day)
,_t(t)
{
cout<<"Date()初始化列表"<<endl;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
void newTest()
{
Time t1;
Date d1(2018,9,30,t1);
}
运行结果:
【1】可以试着猜猜他的运行结果,按照之前所学到的知识也许会猜测运行结果应该是Time() Date()...emmmm到底正不正确呢让我们一起来看看:
运行后,会发现结果比猜测的多了一个Time()Time类的构造函数,这个构造函数是哪里来的呢?通过调试就会发现在非初始化列表Date(int year,int month,int day,const Time& t)与{之间多了一次Time(),其实这里有一个初始化列表但是我们自己没有写,初始化列表不写,编译器也会自动初始化,这个针对的是自定义类型:Time。
下来我们来看看写了初始化列表后的运行结果:
通过对比就会发现,使用初始化列表比不使用初始化列表少调用了一次Time的构造函数,因此使用初始化列表更加高效。初始化列表可以认为是成员变量定义的地方。
3.哪些成员变量必须放在初始化列表里面?
3.1.常量成员变量。(常量创建时必须初始化)----必须要在定义时给一个初始值,之后不可以改变。
3.2.引用类型成员变量。(引用创建时必须初始化)--一个别名,在定义时必须初始化。
3.3.没有缺省构造函数的成员变量。
用一段代码对上面三种成员变量进行测试:
class Time
{
public:
/*Time()
{
cout<<"Time()"<<endl;
_hour = 0;
_minute = 0;
_second = 0;
}*/
Time(const Time& t)
{
_hour = t._hour;
_minute = t._minute;
_second = t._second;
}
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
Date(int year,int month,int day,const Time& t)
:_year(year)
,_month(month)
,_day(day)
,_t(t)
{
}
private:
int _year;
int _month;
int _day;
const int _testConst; //测试const成员变量的初始化
int& _testReFerence; //测试引用成员变量的初始化
Time _t; //测试无缺省(不传值)构造函数的自定义类型成员变量的初始化
};
void newTest()
{
Time t1;
Date d1(2018,9,30,t1);
}
编译代码会发现编译器报错:
通过测试证明结论正确。
4.成员变量按声明顺序初始化,而不是初始化列表。
运行下面代码:
class Date
{
public:
Date(int x)
:_day(x)
,_month(_day)
,_year(x)
{}
void Display()
{
cout<<"year:"<<_year<<endl;
cout<<"month:"<<_month<<endl;
cout<<"day:"<<_day<<endl;
}
private:
int _year;
int _month;
int _day;
};
void newTest()
{
Date d1(1);
d1.Display();
}
来猜猜这段代码运行结果是什么》》》》是 1 1 1么?让我们一起来看看
通过结果发现,很显然不是我们猜测的 1 1 1,它的month竟然是一个随机值,为什么呢?因为
成员变量按声明顺序初始化,而不是初始化列表。所以_day的初始化在_month之后,将_day赋值给_month就是将一个随机值付给了_month,因此就会出现我们所看到的结果。
5.声明和定义的区别:
声明:我告诉编译器我要定义它;
定义:定义时开辟空间。
6.那些类必须自己写构造函数:类中有const类型的成员变量。