一、情景引入
假设我定义了一个Date类:
class Date
{
public:
void Init(int year,int month,int day)
{
_year=year;
_month=month;
_day=day;
}
private:
int _year;
int _month;
int _day;
}
这里我们定义了一个Init 函数来给Date类中的成员变量初始化。但是如果每创建一个Date对象都需要我们调用Init 函数来给Date中的成员变量赋值,显然有点麻烦。那么我们能不能在创建的同时给它赋值呢?就像 int a=10;一样。
这就引出了我们的“构造函数”。
二、概念
构造函数成员函数中特殊的一种。它在创建类类型对象的时候由编译器自动调用。它的作用是对类中的数据成员进行初始化。
三、结构和使用
(1)函数名与类名相同。(2)没有返回值。(3)对象实例化的同时由编译器自动调用。
(4)可以重载。
class Date
{
public:
/*void Init(int year,int month,int day)
{
_year=year;
_month=month;
_day=day;
}*/
//函数名和类名一样,函数名前没有类型,也不用写void。
Date(int year,int month,int day)
{
_year=year;
_month=month;
_day=day;
}
private:
int _year;
int _month;
int _day;
}
构造函数在实例化对象的同时由编译器自动调用,但是初始化的值用户可以自主输入。
Test()
{
Date d1(2022,10,14);
//此处编译器自动调用了构造函数并把2022,10,14分别赋值给了d1中的成员变量
}
以上用法是常用的带参的构造函数的用法,但是构造函数还有无参构造函数等其他类型。详解请看下文。
四、构造函数的分类
一、显式构造函数:由用户自定义编写在类中的构造函数。如上文使用的样例就是显式构造函数。
二、默认构造函数:(可以理解为不传参数就可以调用的构造函数)
(1)编译器默认生成的构造函数:如果类中没有显式定义构造函数,C++编译器会自动生成一个无参的默认构造函数。
注意!编译器默认生成的构造函数在调用的时候,对内置类型不进行处理,只对自定义类型(class/struct/union等)调用它们的默认成员函数来初始化它。
#include <iostream>
using namespace std;
class Test {
int hour;
public:
Test()
{
hour = 0;
}
void print()
{
cout << "test is " << hour << endl;
}
};
class Date
{
//内置类型
int _year;
int _month;
int _day;
//自定义类型
Test _test;
public:
void Print()
{
cout << "year is " << _year << endl;
cout << "month is " << _month << endl;
cout << "day is " << _day << endl;
_test.print();
}
};
int main()
{
Date d;
d.Print();
return 0;
}
结果如下:
(2)全缺省构造函数:C++11中,针对编译器默认生成的构造函数对内置类型的成员变量不进行处理这一缺陷进行了改进——内置类型成员变量在类中声明的时候可以给默认值。
#include <iostream>
using namespace std;
class Test {
int hour;
public:
Test()
{
hour = 0;
}
void print()
{
cout << "test is " << hour << endl;
}
};
class Date
{
//内置类型给了初始值
int _year=2022;//这些是缺省值,而不是初始化
int _month=10;
int _day=1;
//自定义类型
Test _test;
public:
Date()
{}
void Print()
{
cout << "year is " << _year << endl;
cout << "month is " << _month << endl;
cout << "day is " << _day << endl;
_test.print();
}
};
int main()
{
Date d;
d.Print();
return 0;
}
结果如下:
(3)无参构造函数:如下
Date()
{
_year=2022;
_month=10;
_day=1;
}
注意!无参构造函数、全缺省构造函数、编译器默认生成的构造函数都属于默认构造函数。默认构造函数只能有一个,否则会有歧义。
小结:构造函数的作用是初始化对象实例。编译器在实例化对象的同时会自动调用构造函数。构造函数分为显式构造函数和默认构造函数。其中默认构造函数又分为无参构造函数、全缺省构造函数、编译器默认生成的构造函数三类。需要注意,编译器默认生成的构造函数只处理自定义类型的成员变量。