一、类的默认成员函数
默认成员函数就是用户没有显式实现,编译器自动生成的成员函数。在C++中,共有6个默认成员函数,其中前四个尤为重要,分别是:构造函数、析构函数、拷贝构造函数、赋值重载函数。
二、构造函数
构造函数是用来初始化类内部成员的函数,在实例化一个对象时自动调用。
2.1 构造函数的特点
class Date
{
public:
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
//构造函数(全缺省)
Date(int year = 2000, int month = 6, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date date1;//调用构造函数,使用缺省值
Date date2(2005,12,20);//调用构造函数,使用实参值
return 0;
}
三、析构函数
析构函数与构造函数的作用相反,它不是销毁对象本身,而是在对象的生命周期结束时,用来释放对象内的资源(指动态开辟的内存等)的函数。在一个对象的生命周期结束时自动调用。
3.1 析构函数的特点
class Date
{
public:
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
//构造函数(全缺省)
Date(int year = 2000, int month = 6, int day = 1)
{
_year = year;
_month = month;
_day = day;
_a = (int*)malloc(sizeof(int)*5);
}
//析构函数
~Date()
{
free(_a);
}
private:
int _year;
int _month;
int _day;
int* _a;
};
int main()
{
Date date1;//调用构造函数,使用缺省值
Date date2(2005,12,20);//调用构造函数,使用实参值
return 0; //调用 date1 和 date2的析构函数,date2先析构。
}
四、拷贝构造函数
拷贝构造函数是一种特殊的构造函数,它的作用是用现有的一个对象来初始化和这个对象同类型的对象。
4.1 拷贝构造函数的特点
4.2 关于无限递归的原因
//类中的拷贝构造函数
Date(const Date& date)
{
_year = date._year;
_month = date._month;
_day = date._day;
}
int main()
{
Date date(2024, 8, 1);//传值构造
date.Print();
Date date2(date);//拷贝构造
date2.Print();
Date date3 = date2;//拷贝构造,和上面的写法等价
date3.Print();
return 0;
}
五、赋值重载函数
5.1 运算符重载
5.1.1 代码示例
class Date
{
public:
void Print()
{
cout << _year << '/' << _month << '/' << _day << endl;
}
//获取当前的月份天数
int GetMonthDay(int year, int month)
{
static int Month[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 };
if (month == 2 && ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)))
{
return 29;
}
else
return Month[month];
}
//构造函数
Date(int year = 2000, int month = 6, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
//析构函数 可写可不写
~Date(){}
//拷贝构造函数
Date(const Date& date)
{
_year = date._year;
_month = date._month;
_day = date._day;
}
/*===========================================================================*/
//(类外实现)运算符重载函数
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day);
// 日期-天数
Date operator-(int day);
// 日期-=天数
Date& operator-=(int day);
private:
int _year;
int _month;
int _day;
};
Date& Date::operator+=(int day)
{
_day += day;
while (_day > GetMonthDay(_year, _month))
{
_day -= GetMonthDay(_year, _month);
++_month;
if (_month == 13)
{
_year++;
_month = 1;
}
}
return *this;
}
Date& Date::operator-=(int day)
{
_day -= day;
while (_day < 0)
{
_day += GetMonthDay(_year, (_month - 1) == 0 ? 12 : (_month - 1));
--_month;
if (_month == 0)
{
_year--;
_month = 12;
}
}
return *this;
}
// 日期+天数
Date Date::operator+(int day)
{
Date date = *this;
date += day;
return date;
}
// 日期-天数
Date Date::operator-(int day)
{
Date date = *this;
date -= day;
return date;
}
5.1.2 调用示例
int main()
{
Date date(2024, 8, 1);//传值构造
date.Print();
//以下两种写法等价,以+=运算示例
date.operator+=(300);
date += 300;
date.Print();
return 0;
}
5.2 赋值重载
//类中的赋值运算符重载函数
Date& operator=(const Date& date)
{
_day = date._day;
_month = date._month;
_year = date._year;
return *this;
}
int main()
{
Date date(2024, 8, 1);//传值构造
date.Print();
Date date2(2000, 1, 1);
date2.Print();
//赋值重载,以下两种写法等价
date2 = date;
date2.operator=(date);
date2.Print();
return 0;
}