【C++】时间计算器实现代码(注释丰富)

文章目录

  • Date.h
  • Date.cpp
  • DateTest.cpp


Date.h

#pragma once
#include
#include
using namespace std;
#include


// 类里面短小函数,适合做内联函数的,可以直接在类里面定义
// 在类里面定义的函数,会被编译器识别为内联函数

class Date
{
	// 友元声明:放在类里面,前面加上关键字 friend 可以在这个函数里访问权限类中为 private 的成员
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);

public:
	Date(int year = 1900, int month = 1, int day = 1);
	void print() const;


	int GetMonthDay(int year, int month) const;

	Date& operator+=(int day);
	Date operator+(int day) const;
	Date& operator-=(int day);	// 运算符重载可以构成函数重载,date-date有意义,date-day也有意义

	// d1 - 100
	Date operator-(int day) const;
	// d1 - d2
	int operator-(const Date& d) const;

	Date& operator++();	// 有前置和后置
	Date operator++(int);
	Date& operator--();	// 有前置和后置
	Date operator--(int);


	bool operator==(const Date& d) const;
	bool operator!=(const Date& d) const;
	bool operator<(const Date& d) const;
	bool operator<=(const Date& d) const;
	bool operator>(const Date& d) const;
	bool operator>=(const Date& d) const;

private:
	int _year;
	int _month;
	int _day;

};

ostream& operator<<(ostream& out, const Date& d);	// 返回值是 out ,更说明了这个操作符是从左往右的~~
istream& operator>>(istream& in, Date& d);

Date.cpp

#include "Date.h"


Date::Date(int year, int month, int day)
{
	if (year >= 0
		&& (month > 0 && month <= 12)
		&& (day > 0 && day <= Date::GetMonthDay(year, month)))
	{
		_year = year;
		_month = month;
		_day = day;
	}
	else
	{
		cout << "日期非法..." << endl;
	}

}


void Date::print() const
{
	cout << _year << " 年 " << _month << " 月 " << _day << " 日" << endl;
}


//void Date::operator<<(ostream& out)
//{
//	out << _year << " 年 " << _month << " 月 " << _day << " 日" << endl;
//}


ostream& operator<<(ostream& out, const Date& d)
{
	cout << d._year << " 年 " << d._month << " 月 " << d._day << " 日" << endl;
	
	return out;
}

istream& operator>>(istream& in, Date& d)
{
	cin >> d._year;
	if (d._year < 0)
	{
		perror("输入年份非法");
		exit(-1);
	}
	cin >> d._month;
	if (d._month > 12 || d._month <= 0)
	{
		perror("输入月份非法");
		exit(-1);
	}
	cin >> d._day;
	if (d._day > d.GetMonthDay(d._year, d._month) || d._day <= 0)
	{
		perror("输入日期非法");
		exit(-1);
	}

	return in;
}


int Date::GetMonthDay(int year, int month) const
{
	assert(month > 0 && month < 13);
	int monthArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };

	if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0))
	{
		monthArray[2] = 29;
	}

	return monthArray[month];
}


//【 这种复用更好,因为没有拷贝行为!!!! 】
Date& Date::operator+=(int day)	
{
	if (day < 0)
	{
		*this -= -day;
		return *this;
	}

	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;

		if (_month > 12)
		{
			_month -= 12;
			++_year;
		}
	}
	return *this;
}

Date Date::operator+(int day) const
{
	Date tmp(*this);
	tmp += day;

	return tmp;
}

【 这种复用不好 】
//Date Date::operator+(int day)
//{
//	Date tmp = *this;
//
//	tmp._day += day;
//
//	while (tmp._day > GetMonthDay(tmp._year, tmp._month))
//	{
//		tmp._day -= GetMonthDay(tmp._year, tmp._month);
//		++tmp._month;
//
//		if (tmp._month > 12)
//		{
//			tmp._month -= 12;
//			++tmp._year;
//		}
//	}
//	return tmp;	
//}

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



Date& Date::operator-=(int day)	// 运算符重载可以构成函数重载,date-date有意义,date-day也有意义
{
	if (day < 0)
	{
		*this += -day;
		return *this;
	}

	// 借位
	while (day > _day)
	{
		if (_month == 1)
		{
			_month = 12;
			--_year;
		}
		else
		{
			--_month;
		}
		day -= _day;
		_day = GetMonthDay(_year, _month);
	}
	_day -= day;

	return *this;
}

// d1 - 100
Date Date::operator-(int day) const
{
	Date tmp(*this);
	tmp -= day;

	return tmp;
}

// d1 - d2
int Date::operator-(const Date& d) const
{

	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	int count = 0;
	while (max != min)
	{
		++min;
		++count;
	}

	return count * flag;
}



// ++d1     效率更高
Date& Date::operator++()
{
	//cout << "++前置" << endl;
	*this += 1;
	return *this;
}

// d1++	   保存加加之前的值 
Date Date::operator++(int) //-----------------> int没有实际意义,只是为了占位,构成函数重载
{

	//cout << "后置++" << endl;
	Date tmp(*this);	//保存一份才能返回之前的值 出现了拷贝,效率没有前置高!!!
	*this += 1;
	return tmp;
}

// --d1
Date& Date::operator--()
{

	//cout << "--前置" << endl;
	*this -= 1;
	return *this;

}
// d1--
Date Date::operator--(int)//-----------------> int没有实际意义,只是为了占位,构成函数重载
{
	//cout << "后置--" << endl;
	Date tmp(*this);
	*this -= 1;

	return tmp;
}




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

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

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

DateTest.cpp

#include "Date.h"

// 定义
void TestDate1()
{
	Date d1(2023, 3, 17);
	d1.print();

	//Date d2(2023, 2, 29);
	//d2.print();

	Date d2 = d1 + 168;	// 日期加天数,调拷贝构造
	d2.print();
	d1.print();

	d1 += 168;
	d1.print();
}


// 前后置++
void TestDate2()
{
	Date d1(2023, 3, 17);
	d1.print();

	++d1;	// d1.operator++();
	d1.print();

	d1++;	//d1.operator++(0);	--> 编译器自动识别,传了一个整形过去(不一定是这里的0),调用了相应的后置++
	d1.print();
}

void TestDate3()
{
	Date d1(2023, 3, 17);
	d1.print();
	Date d2 = d1 - (-5000);
	d1.print();
	d2.print();

	d1 -= 5000;
	d1.print();
}


void TestDate4()
{
	Date d1(2023, 3, 17);
	d1.print();

	--d1;	// d1.operator--();
	d1.print();

	d1--;	//d1.operator--(0);	--> 编译器自动识别,传了一个整形过去(不一定是这里的0),调用了相应的后置--
	d1.print();
}

void TestDate5()
{
	Date d1(2023, 3, 17);
	Date d2(2017, 10, 23);
	Date d3(2023, 9, 1);

	cout << d1 - d2 << endl;
	cout << d1 - d3 << endl;

}

//void Date::operator<<(ostream& out)

void TestDate6()
{
	// 流插入+允许重载 ----> 也是为了优化 c 的 printf
	// printf 没法打印自定义类型,也没法访问private的成员,因为针对c c 的结构体访问不受限制

	int i = 8888;
	double d = 1.11;
	// 【运算符重载 + 函数重载】:提前设定好了的,所以能自动识别内置类型类型
	cout << i;		// <<也是运算符的重载,cout 是iostream里的一个类,已经定义好了的
					// cout.operator<<(i) --> int
	cout << d << endl;		// cout.operator<<(d) --> double


	// 自定义运算符重载
	Date d1(2023, 3, 17);
	//按照我们成员函数定义写,应该是下面这样 
	// d1.operator<<(cout);
	// d1 << cout;		// 太!奇!怪!啦!
	// 成员对象传入 this就自动抢占了第一个,成为左操作数,那....不写成员里就好咯

	operator<<(cout, d1);
	cout << d1;
	Date d2(2035, 6, 6);
	cout << d1 << d2 << endl;

}

void TestDate7()
{
	// 流提取
	Date d1;
	cout << d1;

	cin >> d1;
	cout << d1;
}


int main()
{
	TestDate1();
	TestDate2();
	TestDate3();
	TestDate4();
	TestDate5();
	TestDate6();
	TestDate7();


	return 0;
}

你可能感兴趣的:(C++,c++)