c++日期类

接上文来完整实现日期类的成员函数,先是日期类的成员变量

class Date
{
public:

private:
    int _year:
    int _month;
    int _day;
}

在写日期类的默认成员函数和运算符重载之前,我们先写一个函数来获得某年某年某月的具体天数,我们定义一个静态数组monthDayArray[]去记录每个月的天数,如果是闰年的二月就返回二十九天,其他情况下返回monthDayArray[month]

int GetMonthDay(int year, int month)
{
	assert(year >= 0 && month >= 0 && month <= 12);
		
	static int	monthDayArray[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	if (month == 2 && isLeapYear(year))
		return 29;
	else
		return monthDayArray[month];
}

这里面还有一个判断闰年的函数要去实现,这个大家应该都会
 

bool isLeapYear(int year)
{
	return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

接下来实现日期类的构造函数,也就是把我们输入的年月日赋值给日期对象,需要注意的是我们输入的数据需要是一个有效的日期,我们需要对这个年月日进行检查,年要大于零,月大于零小于等于十二,日大于零小于等于当月最大天数

Date(int year = 1970, int month = 1, int day = 1)
{
	if (year > 0 && (month > 0 && month < 13) && (day > 0 && day <= GetMonthDay(year,month)))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
		cout << "非法参数" << endl;
}

拷贝构造就很简单了,对年月日进行赋值即可

Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

接下来就是赋值运算符的重载,按照难易顺序来,先来一个==的重载

bool operator==(const Date& d)
{
	return ((_year == d._year) && (_month == d._month) && (_day == d._day));
}

与==相反的是!=,一开始我想的是年不相等或月不相等或日不想等则返回true,但是我们上面已经写了==了,为什么不能把==用起来呢,!=就是==取反,这个思路也让我们下面实现起来更简单

bool operator!=(const Date& d)
{
	return !(*this == d);
}

接下来我们实现<,按照我们上面的思路,我们实现了<也就间接实现了>=,因为<本就与>=对立,<我的实现思路和我们数学上整型比大小类似,我们可以把日期类的对象看成是一个三位数,先比百位,百位相等就去比十位,以此类推

bool operator<(const Date& d)
{
	if (_year == d._year)
	{
		if (_month == d._month)
		{
			return _day < d._day;
		}
		return _month < d._month;
	}
	else
		return _year < d._year;
}

那>=就是<取反了

bool operator>=(const Date & d)
{
	return !(*this < d);
}

>和<=和上面类似,我就只贴代码了

bool operator>(const Date& d)
{
	if (_year == d._year)
	{
		if (_month == d._month)
		{
			return _day > d._day;
		}
		return _month > d._month;
	}
	else
		return _year > d._year;
}

bool operator<=(const Date& d)
{
	return !(*this > d);
}

接下来我们实现+,当然+也有加上多少多少天和加上另一个日期类,我认为日期加日期没有意义,因此就只实现日期加天数,日期加天数是要有返回值的,但是又不能在*this上直接操作,就像是c=a+10;我们的a并不会改变,a不会变成a+10,怎么做呢,我们用拷贝构造创建一个临时对象,在这个临时对象上操作并返回它

至于逻辑实现我们可以把它理解为十进制相加的进位一样,先把天数加到_day里,如果_day大于那个月的天数就进位,月大于十二就进位

Date operator+(int day)
{
	Date temp(*this);
		
	temp._day = temp._day + day;

	while (temp._day > GetMonthDay(temp._year, temp._month))
	{
		temp._day = temp._day - GetMonthDay(temp._year, temp._month);
		temp._month = temp._month + 1;
		if (temp._month > 12)
		{
			temp._month = 1;
			temp._year = temp._year + 1;
		}
	}
	return temp;
}

+=和+的区别就是+=是加在*this上的,返回的是*this

Date operator+(int day)
{
	Date temp(*this);
		
	temp._day = temp._day + day;

	while (temp._day > GetMonthDay(temp._year, temp._month))
	{
		temp._day = temp._day - GetMonthDay(temp._year, temp._month);
		temp._month = temp._month + 1;
		if (temp._month > 12)
		{
			temp._month = 1;
			temp._year = temp._year + 1;
		}
	}
	return temp;
}

-和-=的实现逻辑和上面的类似,也只贴代码了

Date operator-(int day)
{
	Date temp(*this);

	temp._day = temp._day - day;
	while (temp._day <=0)
	{
		temp._month = temp._month - 1;
		if (temp._month == 0)
		{
			temp._month = 12;
			temp._year = temp._year - 1;
		}
		temp._day = temp._day + GetMonthDay(temp._year, temp._month);
	}

	return temp;
}

Date& operator-=(int day)
{
	*this = *this - day;
	return *this;
}

当然还有前后置的自加和自减,有两个问题,一是怎么区分前后置,还有就是前后置的具体实现,如何区别前后置c++已经给了我们解决方案,那就是前置++没有参数,而后置++的参数为(int),那么怎么去实现前置和后置,也就是先自加再运算和先运算再自加,在后置我们可以直接加如何返回,前置只需要对*this进行拷贝,然后*this自加,返回拷贝

Date& operator++()
{
	*this += 1;
	return *this;
}

Date operator++(int)
{
	Date tmp(*this);
	*this += 1;
	return tmp;
}

Date& operator--()
{
	*this -= 1;
	return *this;
}

Date operator--(int)
{
	Date tmp(*this);
	*this -= 1;
	return tmp;
}

Date operator=(const Date& d)
{
	if (this != &d)
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	return *this;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C 语言中,由于没有对象的概念,因此无法像面向对象语言一样使用内嵌子对象。不过,我们可以通过结构体来模拟对象的概念,从而实现类似内嵌子对象的效果。 以日期类为例,我们可以定义一个结构体来表示日期,然后在日期类中嵌入这个结构体作为其成员变量,从而实现日期类的功能。 以下是一个简单的 C 日期类的实现: ``` typedef struct { int year; int month; int day; } Date; typedef struct { Date date; int (*getYear)(const Date *); int (*getMonth)(const Date *); int (*getDay)(const Date *); } DateClass; int getYear(const Date *date) { return date->year; } int getMonth(const Date *date) { return date->month; } int getDay(const Date *date) { return date->day; } DateClass Date_new(int year, int month, int day) { DateClass dateClass = { { year, month, day }, getYear, getMonth, getDay }; return dateClass; } ``` 在上面的代码中,我们首先定义了一个日期结构体 `Date`,表示一个具体的日期。然后,我们定义了一个日期类 `DateClass`,其中包含一个 `Date` 类型的成员变量 `date`,以及三个函数指针,用于获取日期的年、月、日信息。 接着,我们实现了三个函数 `getYear`、`getMonth`、`getDay`,分别用于获取日期的年、月、日信息。最后,我们定义了一个 `Date_new` 函数,用于创建一个新的日期对象,并返回一个 `DateClass` 类型的结构体,该结构体包含了日期对象的所有信息和操作。 使用这个日期类时,我们可以先通过 `Date_new` 函数创建一个日期对象,然后使用该对象的方法获取日期的信息,如下所示: ``` DateClass date = Date_new(2021, 10, 1); printf("Year: %d\n", date.getYear(&date.date)); printf("Month: %d\n", date.getMonth(&date.date)); printf("Day: %d\n", date.getDay(&date.date)); ``` 输出结果为: ``` Year: 2021 Month: 10 Day: 1 ``` 可以看到,我们通过 `Date_new` 函数创建了一个日期对象 `date`,然后使用该对象的方法获取了日期的年、月、日信息,并将其输出到控制台上。这就是一个简单的 C 日期类的实现,其中使用了结构体来模拟对象,并实现了类似内嵌子对象的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值