运算符重载---2

运算符重载---2

  • Test.cpp
  • Date.h
  • Date.cpp

Test.cpp

#include "Date.h"

void TestDate1()
{
	Date d1(2023, 5, 1);
	Date d2(2023, 9, 1);

	cout << (d1 == d2) << endl;
	cout << (d1 != d2) << endl;
	cout << (d1 > d2) << endl;
	cout << (d1 < d2) << endl;
	cout << (d1 >= d2) << endl;
	cout << (d1 <= d2) << endl;
}

void TestDate2()
{
	Date d1(2023, 5, 1);
	Date d2(2023, 9, 1);

	d1 += 50;
	(d1 + 50).Print();

	d2 -= 10;
	(d2 - 10).Print();

	(++d1).Print();
	(d1++).Print();
}

void TestDate3()
{
	Date d1(2023, 5, 1);
	Date d2(2023, 9, 1);
	d1 - d2; //(日期 - 日期)
}


void TestDate5()
{
	const char* WeeDayToStr[] = { "周一","周二","周三","周四","周五","周六","周七" };
	Date d1, d2;
	int day = 0;
	int option = 0;
	do {
		cout << "**********************************" << endl;
		cout << "  1、日期加减天数   2、日期减日期" << endl;
		cout << "  3、日期->周几     -1、退出" << endl;
		cout << "请选择:>" << endl;
		cout << "*********************************" << endl;
		cin >> option;

		if (1 == option)
		{
			cout << "请依次输入日期及天数(减天数就输入负数):";
			cin >> d1 >> day;
			cout << "日期加减天数后的日期:" << d1 + day << endl;
		}
		else if (2 == option)
		{
			cout << "请依次输入两个日期:";
			cin >> d1 >> d2;
			cout << "相差的天数:" << d1 - d2 << endl;
		}
		else if (option == 3)
		{
			cout << "请输入日期:";
			cin >> d1;
			Date start(1, 1, 1);
			int n = d1 - start;
			int weekDay = 0;
			weekDay += n;
			//cout<< "周" << weekDay%7+1 <
			cout << WeeDayToStr[weekDay % 7] << endl;
		}
		else
		{
			cout << "无此选项,请重新输入" << endl;
		}


	} while (option != -1);

}

void TestDate6()
{
	Date d1(2023, 8, 8);
	(d1 + 100).Print();
	(d1 + -100).Print();

	(d1 - -100).Print();

}


//内置类型数据的输入、输出
void TestDate7()
{
	int i = 0;
	double d = 1.1;
	//这儿满足运算符重载和函数重载;
	//A 库里面写好了运算符重载
	//B 自动识别类型,它们构成函数重载(底层是 函数名修饰规则) 

	//cout << i;  //转化为:cout.operator<<(&cout,i);【cout自己去重载运算符】----- 运算符重载为:ostream& operator<<(ostream* const this,int i)
	//cout << d;
	//在C++库中,cout 作为 ostream类的对象;cin 作为 istream类的对象

   //补充:运算符重载和函数重载虽然都用了重载这个词,但是它们之间没有必然联系。
   // 运算符重载:函数(自定义类型的对象遇到运算符,就调用相应的函数)
   // 函数重载:函数名相同但参数不同的函数同时存在


	Date d1(2022, 7, 25);
	Date d2(2022, 7, 26);
	//实现: d1<
	//d1 << cout; // 它的原身函数是下面一行的函数。 (自定义类型对象遇到运算符,就构成运算符重载,进而转化为重载(原身)函数)
	//d1.operator<<(cout);

	cout << d1 << d2;
	//从左往右,支持连续的输出(要有返回值:ostream&)[cout<
	// 同样的是:d1=d2=d3; 从右往左,支持连续的赋值(要有返回值:Date&)[d2=d3 的返回值为 d2,然后再操作 d1=d2 ]

	int day = 1;
	//cout << (d1+100);
	cin >> d1 >> day;
	cin >> d1 >> d2;
	cout << d1 << d2;
}

int main()
{
	TestDate1();

	return 0;
}

Date.h

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

class Date
{
	//友元函数——这个函数内部可以使用 Date对象访问私有/保护成员
	friend inline ostream& operator<<(ostream& out, const Date& d);
	friend inline istream& operator>>(istream& in, Date& d);

public:
	//需要频繁调用的函数,在类内定义,实现inline (减少创建栈帧的消耗,提升效率)

	//构造函数
	Date(int year = 1, int month = 1, int day = 1)
	{
		this->_year = year;
		_month = month;
		_day = day;

		assert(this->CheckDate());  //assert(),断言里面是true不报错,false报错。
	}

	//打印日期
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}

	//获取某年某月的天数
	int GetMonthDay(int year, int month)
	{
		static int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		int day = days[month];
		if (2 == month
			&& ((0 == year % 4 && year % 100 != 0) || (0 == year % 400)))
		{
			day += 1;
		}
		return day;
	}

	//检查日期是否正确
	bool CheckDate()
	{
		if (_year >= 1
			&& _month > 0 && _month < 13
			&& _day>0 && _day <= GetMonthDay(_year, _month))
			return true;
		else
			return false;
	}


	//比较大小类的重载函数(运算符重载)
	bool operator==(const Date& d);
	bool operator!=(const Date& d);
	bool operator>(const Date& d);
	bool operator>=(const Date& d);
	bool operator<(const Date& d);
	bool operator<=(const Date& d);

	// d1+100; 
	Date operator+(int day);
	// d1+=100;
	Date& operator+=(int day);

	// d1-100;
	Date operator-(int day);
	// d1-=100;
	Date& operator-=(int day);


	//直接按特性重载,无法区分前置++ 和 后置++。因此特殊处理,使用重载区分,后置++重载增加一个int参数 跟前置++构成函数重载进行区分。
	// ++d1;
	Date& operator++();
	// d1++;
	Date operator++(int);

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

	//实现: d1<
	void operator<<(ostream& out); //out作为cout的形参

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


//全局函数
//如何在类外面访问 类里面私有的成员变量? 友元
// 
// cout << d1; 输出
//会频繁的调用
inline ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "/" << d._month << "/" << d._day << endl;
	return out;
}


// cin >> d1; 输入
//会频繁的调用
inline istream& operator>>(istream& in, Date& d)
{
	in >> d._year >> d._month >> d._day;
	assert(d.CheckDate());

	return in;
}

Date.cpp

#include "Date.h"

//运算符重载
// 一个类到底要重载哪些运算符呢? 解:看哪些运算符对这个类有意义。
// 任何一个类,只需要写 > == 或者 < ==的运算符重载,剩下的比较运算符重载复用即可。

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

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

// d1 > d2;
bool Date::operator>(const Date& d)
{
    if ((_year > d._year)
        || (_year == d._year && _month > d._month)
        || (_year == d._year && _month == d._month && _day > d._day))
        return true;
    else
        return false;
}

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

// d1 >= d2
bool Date::operator>=(const Date& d)
{
    return (*this > d) || (*this == d);
}

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


// d1+100 (d1不改变,返回值需要额外设置)
Date Date::operator+(int day)
{
    Date ret(*this); // 拷贝构造
    ret += day;

    return ret;
}

// d2 += d1 += 100 (d1发生改变,返回值直接传d1就可以)
Date& Date::operator+=(int day)
{
    if (day < 0)
    {
        return *this -= -day;
    }

    _day += day;
    while (_day > GetMonthDay(_year, _month)) // 如果 _day不合法,就处理到合法
    {
        _day -= GetMonthDay(_year, _month);
        ++_month;
        if (13 == _month)
        {
            ++_year;
            _month = 1;
        }
    }

    return *this;
}

Date Date::operator-(int day)
{
    Date ret(*this);
    ret -= day;

    return ret;
}


Date& Date::operator-=(int day)
{
    if (day < 0)
    {
        return *this += -day;
    }

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

    return *this;
}


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

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

    return tmp;
}

// d1-d2
int Date::operator-(const Date& d)
{
    int flag = 1;
    Date max = *this;
    Date min = d;
    if (*this < d)
    {
        max = d;
        min = *this;
        flag = -1;
    }

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

    return n * flag;
}


//实现: d1<
void Date::operator<<(ostream& out) //out作为cout的形参,也是别名(在C++库里面,支持 cout<<自定义类型数据 )
{
    out << _year << "/" << _month << "/" << _day << endl;
}


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