定义
构造函数是一个特殊的成员函数,名字和类名相同,创建类类型对象时由编译器自动调节,保证每个数据成员都有一个合适的初始值,并且在对象的声明周期内只调用一次。
特性
1.函数名和类名相同
2.无返回值
3.对象实例化时编译器自动调用对应的构造函数
4.构造函数可以重载(本质就是,我们可以写多个构造函数,提供多种初始化方式)
class Date
{
public:
Date() //无参构造函数
{
_year = 1;
_month = 1;
_day = 1;
}
Date(int year, int month, int day) //有参构造函数
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1; //定义一个Date对象的时候自动调用无参构造函数
Date d2(2007,7,20); //自动调用有参的构造函数(有参函数调用时,参数写在对象后面,而不是函数的后面)
Date d3(); //因为编译器分不清这是在定义新的函数还是在调用函数,所以会报错,不可以这样写!
}
全缺省参数
1.全缺省参数和无参的构造函数、我们没写编译器默认生成的都称为默认构造函数(我们不写,编译器会自动生成),并且默认构造函数只能有一个。注意:无参构造函数、全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。
//默认构造函数
class Date
{
public:
Date()
{
_year = 1;
_month = 1;
_day = 1;
}
Date(int year = 1, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1;//调用产生歧义
}
所以全缺省函数和无参构造函数在语法上可以同时存在,但是调用时会产生歧义,这时我们会选择保留全缺省函数(灵活:想传几个参数就传几个参数,不传参时可视为无参构造函数,全传时可视为有参构造函数)
2.缺省参数可以避免栈的扩容
我们知道realloc扩容,有可能是原地扩容,也有可能是异地扩容。而异地扩容的代价也是比较大的。不光要找一个更大的空间,还要把原来的数据进行拷贝。所以缺省参数对栈来说还是很好用的。
Stack(size_t n = 4)//栈的无参构造函数改造
{
if (n == 0)
{
capacity = top = 0;
a = nullptr;
}
else
{
a = (int*)malloc(sizeof(int) * n);
if (a == NULL)
{
perror("malloc fail::");
return;
}
capacity = n;
top = 0;
}
}
默认构造函数
编译器生成的默认构造函数的特点:
1.我们不写才会生成一个无参的构造函数,我们写了任意一个构造函数,无参构造函数就不会生成了。(所以写了有参构造函数之后,也要写上无参构造函数)
写了这一个半缺省的函数,那么该类的无参构造函数就算你没写,也不会自动生成了。除非你一个构造函数都没写。
2.内置类型的成员不会处理
3.自定义类型的成员才会处理,会去调用这个成员的构造函数
总结:一般情况下,都需要我们自己写构造函数,决定初始化的方式。除非,这个类的成员变量全是自定义类型。