[Operator Overloading]The Date class (version 3)

本文档介绍如何在Date类中实现操作符`+=`, `-=`,`+`和`-`的重载,以支持如`f()`函数所示的日期运算。示例代码包括`framework.cpp`和`source.h`两个文件,`f()`函数的输出将展示这些重载操作符的使用效果。" 117021475,10491298,掌握PostgreSQL 13:一本实践指南,"['postgresql', '数据库', 'sql', '数据库管理', '技术图书']

Description

Implement the operator +=, -=, +, -, in the class Date

class Date
{
public:
  Date(int y=0, int m=1, int d=1);  
  static bool leapyear(int year);
  int getYear() const;
  int getMonth() const;
  int getDay() const;

  // add any member you need here  
};

You implementation should enable the usage like this:

void f()
{
  Date date = d;

  cout << "date = " << date << endl;
  cout << "date+1 = " << date+1 << endl;
  cout << "date-1 = " << date-1 << endl;

  date+=366;
  cout << "date = " << date << endl;
  date-=365;
  cout << "date = " << date << endl;
  date-=-365;
  cout << "date = " << date << endl;
  date+=-366;
  cout << "date = " << date << endl;

  cout << endl;
}

The output of f() should be:

date = 2004-2-28
date+1 = 2004-2-29
date-1 = 2004-2-27
date = 2005-2-28
date = 2004-2-29
date = 2005-2-28
date = 2004-2-28

提交时不需要提交operator << 重载。

framework.cpp
#include<iostream>
#include<string>
#include"source.h"
using namespace std;

ostream& operator<<(ostream& os, const Date& date)
{
  os << date.getYear() << "-" << date.getMonth() << "-" << date.getDay();
  return os;
}

/* 
f1() test for:
  constructor, copy constructor, assign assignment
  static member function leapyear()
  operator ==, !=, <, <=, >, >=
*/
void f1()
{
  Date date1, date2(2003,1,1);
  Date date3 = Date(2007,2,28);
  cout << "date1: " << date1 << endl;
  cout << "date2: " << date2 << endl;
  
  cout << "date3 after copy constructor: " << date3 << endl;
  date3 = date1;
  cout << "date3 after copy asignment: " << date3 << endl;  

  cout << "year 1996 is leap year? " << Date::leapyear(1996) << endl;
  cout << "year 1200 is leap year? " << Date::leapyear(1200) << endl;
  cout << "year 1300 is leap year? " << Date::leapyear(1300) << endl;
  cout << "year 1999 is leap year? " << Date::leapyear(1999) << endl;

  cout <<  "(date1==date3)? " << (date1==date3) << endl;
  cout <<  "(date1!=date3)? " << (date1!=date3) << endl;
  cout <<  "(date1==date2)? " << (date1==date2) << endl;
  cout <<  "(date1!=date2)? " << (date1!=date2) << endl;

  cout <<  "(date1<date1)? " << (date1<date1) << endl;
  cout <<  "(date1<=date1)? " << (date1<=date1) << endl;
  cout <<  "(date1<date2)? " << (date1<date2) << endl;
  cout <<  "(date1<=date2)? " << (date1<=date2) << endl;
  
  cout <<  "(date1>date1)? " << (date1>date1) << endl;
  cout <<  "(date1>=date1)? " << (date1>=date1) << endl;
  cout <<  "(date1>date2)? " << (date1>date2) << endl;
  cout <<  "(date1>=date2)? " << (date1>=date2) << endl;

}
/*
f2() test for:
  subscript opeartor [] as both lvalue and rvalue
*/
void f2()
{
  Date date1(2011,4,1);
  cout << "date1: " << date1 << endl;
  cout << date1["year"] << endl;
  cout << date1["month"] << endl;
  cout << date1["day"] << endl;  
  date1["year"] = 2000;
  date1["month"] = 10;
  date1["day"] = 10;
 
  cout << "date1: " << date1 << endl;
}

/*
f3_0() test for:
  operator 
  +=, -=, 
  +, -, 
*/
void f3_0(const Date& d)
{
  Date date = d;

  cout << "date = " << date << endl;
  cout << "date+1 = " << date+1 << endl;
  cout << "date-1 = " << date-1 << endl;

  date+=366;
  cout << "date = " << date << endl;
  date-=365;
  cout << "date = " << date << endl;
  date-=-365;
  cout << "date = " << date << endl;
  date+=-366;
  cout << "date = " << date << endl;
      
  cout << endl;
}
/*
f3_1() test for:
  operator 
  ++(prefix), --(prefix), 
  ++(postfix), --(postfix), 
  +=, -=, 
  +, -, 
  <<
*/

void f3_1(const Date& d)
{
  Date date = d;
  cout << "date = " << date << endl;
  cout << "++date = " << ++date << endl;
  cout << "--date = " << --date << endl;
  cout << "date++ = " << date++ << endl;
  cout << "date-- = " << date-- << endl;
  cout << "date = " << date << endl;
  date+=366;
  cout << "date = " << date << endl;
  date-=365;
  cout << "date = " << date << endl;
  date-=-365;
  cout << "date = " << date << endl;
  date+=-366;
  cout << "date = " << date << endl;
      
  cout << endl;
}

void f3()
{
  Date date1, date2(2004,2,28), date3(2007,2,28),date4(2000,2,28),date5(99,12,31);
  f3_0(date1);
  f3_0(date2);
  f3_0(date3);
  f3_0(date4);
  f3_0(date5);
}


int main()
{
  f3();
  //system("PAUSE");
  return 0;
}

source.h
#include<iostream>

using namespace std;

class Date
{
public:
    Date(int y = 0, int m = 1, int d = 1);
    Date(const Date & another);
    
    static bool leapyear(int year);
    int getYear() const;
    int getMonth() const;
    int getDay() const;

    Date & operator=(const Date & another);

    bool operator==(const Date & another)const;
    bool operator!=(const Date & another)const;
    bool operator> (const Date & another)const;
    bool operator>=(const Date & another)const;
    bool operator< (const Date & another)const;
    bool operator<=(const Date & another)const;
    
    Date & operator++();
    Date  operator++(int);
    Date & operator--();
    Date  operator--(int);
    
    Date & operator+=(int day);
    Date  operator+ (int day)const;
    Date & operator-=(int day);
    Date  operator- (int day)const;
    
    int operator-(const Date& another)const;
    int & operator[](string  str);
    
private:
    int _year;
    int _month;
    int _day;
};

Date::Date(int y, int m, int d)
	:_year(y),_month(m),_day(d){}
Date::Date(const Date & another)
{
	this->_day = another._day;
	this->_month = another._month;
	this->_year = another._year;
}

bool Date::leapyear(int year)
{
    return ((year%400)==0||(year%4==0&&year%100!=0));
}
int Date::getYear() const
{
    return _year;
}
int Date::getMonth() const
{
    return _month;
}
int Date::getDay() const
{
    return _day;
}

Date & Date::operator=(const Date & another)
{
	this->_day = another._day;
	this->_month = another._month;
	this->_year = another._year;
	return *this;
}

bool Date::operator==(const Date& another)const
{
    return _year == another._year && _month == another._month && _day == another._day;
}
bool Date::operator!=(const Date& another)const
{
    return !(*this == another);
}
bool Date::operator>(const Date& another)const
{
    return ((_year > another._year )||(_year == another._year && _month > another._month )||(_month == another._month && _day > another._day));
}
bool Date::operator>=(const Date& another)const
{
    return ((*this == another)||(*this > another));
}
bool Date::operator<(const Date& another)const
{
    return !(*this >= another);
}
bool Date::operator<=(const Date& another)const
{
    return !(*this > another);
}

static const int Monthdays[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static int GetMonthDays(int year,int month)
{
    if (month == 2 && (Date::leapyear(year)))
        return 29;
    else
    	return Monthdays[month];
}
Date & Date::operator++()
{
    if (_day + 1 > GetMonthDays(_year, _month))
        if (_month + 1 == 13)
        {
            _year++;
            _month = 1;
            _day = 1;
        }
        else
        {
            _month++;
            _day = 1;
        }
    else
        _day++;
    return *this;
}
Date Date::operator++(int)
{
    Date ret(*this);
    ++(*this);
    return ret;
}
Date& Date::operator--()
{
    if (_day == 1)
        if (_month == 1)
        {
            _year--;
            _month = 12;
            _day = 31;
        }
        else
        {
            _month--;
            _day = GetMonthDays(_year, _month);
        }
    else
        _day--;
    return *this;
}
Date Date::operator--(int)
{
    Date ret(*this);
    --(*this);
    return ret;
}

Date& Date::operator+=(int day)
{
    _day += day;
    if (_day > 0)
    {
        while (_day > GetMonthDays(_year, _month))
        {
        	_day -= GetMonthDays(_year, _month);
            if(_month == 12)
            {
                _month = 1;
                _year++;
            }
            else
                _month++;
            //_day -= GetMonthDays(_year, _month);
        }
    }
    if (_day <= 0)
    {
        while (_day < 1)
        {
            if(_month == 1)
            {
                _month = 12;
                _year--;
            }
            else
                _month--;
            _day += GetMonthDays(_year, _month);
        }
    }
    return *this;
}
Date Date::operator+(int day)const
{
    Date ret = (*this);
    return ret += day;
}
Date& Date::operator-=(int day)
{
    //return (*this) += -day;
    _day -= day;
    if (_day > 0)
    {
        while (_day > GetMonthDays(_year, _month))
        {
        	_day -= GetMonthDays(_year, _month);
            if(_month == 12)
            {
                _month = 1;
                _year++;
            }
            else
                _month++;
 //           _day -= GetMonthDays(_year, _month);
        }
    }
    if (_day <= 0)
    {
        while (_day < 1)
        {
            if(_month == 1)
            {
                _month = 12;
                _year--;
            }
            else
                _month--;
            _day += GetMonthDays(_year, _month);
        }
    }
    return *this;
}
Date Date::operator-(int day)const
{
    //return *this + (-day);
    Date ret = (*this);
    return ret -= day;
}

int Date::operator-(const Date & another)const
{
    if (*this < another)
        return another - *this;
    if (*this == another)
        return 0;

    int ret = 0;
    Date tmp= *this;
    if (tmp._month == 2 && tmp._day == 29)
    {
        tmp._day--;
        ret++;
    }

    if (tmp._month >2)
    {
        while (tmp._year != another._year)
        {
            (tmp._year % 400 == 0 || (tmp._year % 100 != 0 && tmp._year % 4 == 0)) ?
                ret += 366 : ret += 365;
            tmp._year--;
        }
    }
    else
    {
        while (tmp._year != another._year)
        {
            tmp._year--;
            leapyear(tmp._year) ? ret += 366 : ret += 365;
        }
    }
    while (tmp._month != another._month)
    {
        ret += tmp._day;
        tmp._month--;
        tmp._day = GetMonthDays(tmp._year, tmp._month);
    }
    ret += tmp._day - another._day;
    return ret;
}
int  & Date::operator[](string  str)
{
    string temp = str;
    if(temp == "year")
        return _year;
    else if(temp == "month")
        return _month;
    else if(temp == "day")
        return _day;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值