构造函数
构造函数的概念
当我们在使用一个类时,总是会涉及到对成员变量的初始化,那么谁来对这些成员变量进行初始化捏?这时构造函数就出来了,构造函数虽然名字里有一个构造,但实际上其并非开空间创造对象,而是初始化对象,例如如下的一个日期类:
class date
{
public:
date()//当然这两个date可以合并成一个全缺省函数,相当的好
{
_year=1;
_month=1;
_day=1;
}
date(int year,int month,int day)
{
_year=year;
_month=month;
_day=day;
}
}
int main()
{
date d2;//调用无参构造函数,后面不能加括号
date d2(2003,9,20);//调用带参构造函数
d2.print();
return 0;
}
构造函数的特性
1、函数名与类名相同;
2、无返回值;
3、对象实例化的时候自动调用;
4、构造函数可以重载,我们可以设计多个构造函数,来应对不同的初始情况;
5、无显式定义时,编译器会自动生成,值得注意的是,一旦你写了构造函数,编译器将不再生成,所以当我们在设计构造函数时,不要漏下一个成员变量!!!
6、编译器自动生成的默认构造函数对内置类型不会处理,而对于自定义类型,编译器会调用该成员的构造函数
7、构造函数体对成员变量的初始化是先定义再赋值的流程,所以我们可以想见一些无法赋值的成员变量是构造函数体无法解决滴。
构造函数初始化列表
初始化列表引入
当我们在使用构造函数对以下的成员进行构造程序是否能够进行编译呢?
const int rest_book;
int &all_book;
答案是不行的,因为构造函数本质上是先初始化再赋值,而常性变量和未实例化的引用变量是否能复制呢,很明显是不能的,这时候我们想能否有一个方式让我们直接初始化数据成员呢,所以初始化列表来了!
初始化列表的使用
以如下初始化列表为例:
lib_book(const int rest, int all)
:rest_book(rest)
,all_book(all)
{};//没错,这里面可以空着
可见初始化列表以“:”开始,以“,”衔接,建议uu们都使用初始化列表,在一些类中,初始化和赋值关乎底层效率的问题,因为初始化列表是直接初始化数据成员,并且一些成员必须被初始化,当然初始化列表和构造函数体可以混着用啦~~
初始化列表的特性
1、初始化列表是成员开空间的地方;
2、初始化列表是成员变量首先执行的地方;
3、编译器运行时,按照声明的顺序进行初始化列表,而非初始化列表里的顺序;
4、引用成员变量、const成员变量、自定义类型成员(且没有默认构造函数的)一定要在初始化列表进行初始化;
5、每个成员变量仅能在初始化列表出现一次。