一、类中的6个默认成员函数
如果一个类中什么都没有,那么这个类就是一个空类。但空类中并不是真的什么都没有,编译器会自动生成6个默认成员函数
分别是构造函数、析构函数、拷贝构造函数、赋值重载函数、普通对象取地址函数、const对象取地址函数
本篇博客讲解构造函数相关知识
二、构造函数的引入
对于如下Date类,实例化对象时可以通过调用成员函数Init来初始化,但如果每次创建对象时都使用该方法来初始化对象,未免有些麻烦。
因此,C++中引入了构造函数,可以在对象创建时就将其初始化。
//func.h
class Date {
private:
int _year;
int _month;
int _day;
public:
//初始化
void Init(int year, int month, int day);
//打印
void Print();
};
三、构造函数特性
1.构造函数是一个特殊的成员函数,函数名与类名相同
2.当类中没有显式实现构造函数时,编译器会自动生成构造函数;当类中有显式实现构造函数时,编译器不会生成构造函数
3.构造函数在创建类类型对象时由编译器自动调用,以保证每个成员变量都能被初始化,在对象整个生命周期中只被调用一次
4.构造函数无返回值
5.构造函数可以重载
四、构造函数的显式实现
注意:当调用无参构造函数来实例化对象时,无需在对象后加 () ,因为无法与函数声明区分。
例如,实例化对象d1,Date d1即可,如果使用 Date d1(),编译器会认为这是一个函数名为d1、返回值类型为Date类的函数声明。
//func.h
class Date {
private:
int _year;
int _month;
int _day;
public:
//打印
void Print();
//无参构造函数
Date();
//有参构造函数
Date(int year, int month, int day);
};
//func.cpp
//打印
void Date::Print()
{
cout << _year << " " << _month << " " << _day << endl;
}
//无参构造函数
Date::Date()
{
_year = 1;
_month = 1;
_day = 1;
}
//有参构造函数
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
//test.cpp
int main()
{
Date d1;
d1.Print();
Date d2(2024, 2, 2);
d2.Print();
return 0;
}
实际上,无参构造函数可以用全缺省构造函数替代
//func.h
//有参构造函数
Date(int year = 1, int month = 1, int day = 1);
//func.c
//有参构造函数
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
五、默认构造函数的用处
首先明白:无参构造函数、全缺省构造函数、编译器默认生成的构造函数都是默认构造函数。(不需要传参就可以调用的构造函数都可以叫默认构造函数)
默认构造函数不会对内置数据类型进行初始化,但是对于自定义类型数据,该默认构造函数会调用自定义类型数据的构造函数来初始化。
如果已经显式定义了构造函数,该构造函数对于自定义类型数据也会调用其构造函数。
例如,在Date类中再设置一个Time类对象(自定义类型),不显式定义构造函数,那么创建Date类对象时编译器会生成默认构造函数,该默认构造函数调用Time类的构造函数,初始化自定义类型 time 。
class Time {
private:
int _hour;
int _minute;
int _second;
public:
//无参构造函数
Time()
{
cout << "Time(int hour, int minute, int second)" << endl;
_hour = 0;
_minute = 0;
_second = 0;
}
};
class Date {
private:
int _year;
int _month;
int _day;
Time _time;
public:
//打印
void Print()
{
cout << _year << " " << _month << " " << _day << endl;
}
};
int main()
{
Date d1;
d1.Print();
return 0;
}
C++11中,对于内置类型数据不初始化的缺陷,进行了优化,允许内置类型数据在类的声明中给予默认值。代码如下:
class Date {
private:
int _year = 1;
int _month = 1;
int _day = 1;
Time _time;
public:
//打印
void Print()
{
cout << _year << " " << _month << " " << _day << endl;
}
};