(C++)默认成员函数(下):日期类的实现

默认成员函数(下):日期类的实现

  • 一、构思文件结构
    • Date.h——包含类的基本结构
    • Date.cpp——各种函数实现
    • test.cpp——测试函数以及main函数所在文件
  • 二、编写默认成员函数
  • 三、编写类的功能函数
    • 1、operater+=(int day)、operater+(int day)
      • 思考实现:日期+天数=日期
      • 功能测试
    • 2、operator++()、operator++(int)
    • 3、operater-=(int day)、operater-(int day)
    • 4、operator--()、operator-=(int)
    • 5、比较运算符
    • 6、日期-日期
      • 实现思路
      • 代码示例
  • 四、编写代码的注意事项

一、构思文件结构

Date.h——包含类的基本结构

#include <iostream>
class Date {
public:
	void Print();//用于打印日期的成员函数,声明和定义分离
private:
	int _year;
	int _month;
	int _day;
};

Date.cpp——各种函数实现

void Date::Print() {
	std::cout << _year << " " << _month << " " << _day << std::endl;
}

test.cpp——测试函数以及main函数所在文件

二、编写默认成员函数

根据上、中两节的分析,构造函数要写
析构、拷贝构造、赋值重载默认可用
构造函数属于频繁调用的小函数,可以写在类里面内联

#include <iostream>
class Date {
public:
	Date(int year = 1, int month = 1, int day = 1) {
		_year = year;
		_month = month;
		_day = day;
	}
	void Print() {
	std::cout << _year << " " << _month << " " << _day<<std::endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

三、编写类的功能函数

主要就是运算符重载,类的功能函数在Date.cpp中实现,测试在test.cpp中实现。
需求是什么,函数就怎么写

1、operater+=(int day)、operater+(int day)

思考实现:日期+天数=日期

重点是实现月份和年份的进位运算
2025 2 10
+ 50
60-28
3 32-31
4 1
运算需要已知每月天数+判断日期什么时候合法
故编写功能函数int GetMonthDay(int year,int month)
因为此函数在日期运算时频繁调用,所以把它写入类里面作为内联函数使用
Date.h:

#include <iostream>
class Date {
public:
	Date(int year = 1, int month = 1, int day = 1) {
		_year = year;
		_month = month;
		_day = day;
	}
	int GetMonthDay(int year, int month) {
		static int months[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		//为了序号好看编号0的第一个位置跳个位
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0)||year%400==0)) {
			return 29;
		}
		else {
			return months[month];
		}
	}
private:
	int _year;
	int _month;
	int _day;
};

可以先编写operator+=(因为这个可以直接使用类的成员实现),再复用operator+=实现+

Date& Date::operator+=(int day) //能用引用返回就用,减少拷贝次数
{
	_day  += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		if (_month < 12) {
			_month++;
		}
		else {
			_year++;
			_month = 1;
		}
	}
	return *this;//即返回Date变量本身
}

Date Date::operator+(int day)
{
	Date tmp = *this;//或者写Date tmp(*this)
	tmp += day;
	return tmp;//即返回Date变量本身
}

功能测试

编写完一块功能函数以后就马上写代码测试一下,写在test.cpp中,后文功能的测试代码不再一一给出。
测试代码

#include "Date.h"
void test1(){
	Date d1(2025, 3, 9);
	d1.Print();
	Date d2 = d1 + 100;
	d1.Print();
	d2.Print();
	d1 += 100;
	d1.Print();
}

int main() {
	test1();
	return 0;
}

运行结果

在这里插入图片描述

2、operator++()、operator++(int)

operator++()前置++
operator++(int) 后置++
代码

//++d1
Date& Date::operator++() {
	*this += 1;
	return *this;
}
//d1++
Date Date::operator++(int) {
	Date tmp = *this;
	*this += 1;
	return tmp;
}

测试

void test2() {
	Date d1(2025, 3, 9);
	Date ret1 = ++d1;
	d1.Print();
	ret1.Print();
	Date ret2 = d1++;
	d1.Print();
	ret2.Print();
}
int main() {
	test2();
	return 0;
}

测试结果
在这里插入图片描述

3、operater-=(int day)、operater-(int day)

Date& Date::operator-=(int day)
{
	_day -= day;
	while (_day <= 0) {
		_month--;
		if (_month == 0) {
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

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

4、operator–()、operator-=(int)

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

做完以后注意处理一下一些bug,比如如果date+=负数,date-=负数的处理(+和-不需要处理,因为里边包含了+=,-=的运算)

Date& Date::operator+=(int day) 
{
	if (day < 0) {
		return *this -= -day;
	}
	_day  += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		if (_month < 12) {
			_month++;
		}
		else {
			_year++;
			_month = 1;
		}
	}
	return *this;//即返回Date变量本身
}
Date& Date::operator-=(int day)
{
	if (day < 0) {
		return *this += (-day);
	}
	_day -= day;
	while (_day <= 0) {
		_month--;
		if (_month == 0) {
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year, _month);
	}
	return *this;
}

5、比较运算符

注意利用好比较运算时的互斥关系!可以多复用代码实际上只用编写三个运算符,剩余运算符都可以靠复用完成了。

bool Date::operator<(const Date d) 
{
	if (_year < d._year)
		return true;
	else if (_year == d._year && _month < d._month)
		return true;
	else if (_year == d._year && _day < d._day)
		return true;
	else
		return false;
}
bool Date::operator==(const Date d)
{
	return _year == d._year &&
		_month == d._month &&
		_day == d._day;
}
bool Date::operator<=(const Date d)
{
	return *this < d || *this == d;
}
bool Date::operator>(const Date d)
{
	return !(*this <= d);
}
bool Date::operator>=(const Date d)
{
	return !(*this < d);
}
bool Date::operator!=(const Date d)
{
	return !(*this == d);
}

6、日期-日期

实现思路

思路1
在这里插入图片描述
思路2
让较小的天数一直++直到其等于较大的天数,记录++的次数即为相差的天数。——效率上有所降低但实现上最简单。

代码示例

//日期-日期=天数
int Date::operator-(const Date d)
{
	//先假设前面的日期大后面的日期小,如果反了再调换
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (max < min) {
		max = d;
		min = *this;
		flag = -1;//设置flag标记调换过顺序,返回的时候返回负数
	}
	int n = 0;
	while (min != max) {
		min++;
		n++;
	}
	return n*flag;
}

四、编写代码的注意事项

1、写代码勤测试,测试是调试、打印、画图结合的过程,要懂方法、有耐心。
2、写功能函数,一定从功能出发设计。
3、在代码正确的情况下注意代码效率问题,比如:
引用能用则用,减少拷贝数量。
函数逻辑能复用则复用,减少代码量。
多次调用的小函数写成内联函数,一般函数声明与定义分离。
4、写代码勤注释,既是要让别人看懂,也是要让未来的自己看懂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值