Разработка класса date - перегрузка операторов

Пример разработки класса date

В следующем примере реализована перегрузка различных операторов.

#include <iostream>
#include <iomanip>

using namespace std;

const int MONTHS[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

class date
{
    int m_day, m_year, m_month;

 public:
    static int date_counter;

    date(int d=1, int m=1, int y=2017)
    {
        date_counter++;
        m_day = d;
        m_month = m;
        m_year = y;
    }

    ~date()
    {
        date_counter--;
    }

    int day() const
    {
        return m_day;
    }

    int month() const
    {
        return m_month;
    }

    int year() const
    {
        return m_year;
    }

    static bool is_leap(int y)
    {
        return (y % 4 == 0 && y % 100 != 0) || y % 400 == 0;
    }

    date & operator ++()
    {
        ++m_day;
        if (m_day > MONTHS[m_month] + (m_month == 2 && date::is_leap(m_year)))
        {
            m_day = 1;
            ++m_month;
        }
        if (m_month == 13)
        {
            m_month = 1;
            ++m_year;
        }
        return *this;
    }

    date operator ++(int)
    {
        date saved(*this);
        ++(*this);
        return saved;
    }

    bool operator == (const date & right) const
    {
        return m_day == right.m_day && m_month == right.m_month && m_year == right.m_year;
    }

    bool operator < (const date & right) const
    {
        return m_year < right.m_year || (m_year == right.m_year && m_month < right.m_month)
            || (m_year == right.m_year && m_month == right.m_month && m_day < right.m_day);
    }

    bool operator > (const date & right) const
    {
        return right < *this;
    }

    friend date & operator -- (date &);
    friend istream & operator >> (istream &, date &);

};

bool operator != (const date & left, const date & right)
{
    return !(left == right);
}

bool operator <= (const date & left, const date & right)
{
    return left.year() < right.year() || (left.year() == right.year() && left.month() < right.month())
       || (left.year() == right.year() && left.month() == right.month() && left.day() <= right.day());
    // return left < right || left == right;
}

bool operator >= (const date & left, const date & right)
{
    return right >= left;
}

date & operator -- (date & tmp)
{
    --tmp.m_day;
    if (tmp.m_day == 0)
    {
        --tmp.m_month;
        if (tmp.m_month == 0)
        {
            tmp.m_month = 12;
            --tmp.m_year;
        }
        tmp.m_day = MONTHS[tmp.m_month] + (tmp.m_month == 2 && date::is_leap(tmp.m_year));
    }
    return tmp;
}

date operator -- (date & tmp, int)
{
    date saved = tmp;
    --tmp;
    return saved;
}

date operator+(const date & left, int n)
{
    date res(left);
    while (n > 0)
    {
        ++res;
        n--;
    }
    while (n < 0)
    {
        --res;
        n++;
    }
    return res;
}

date operator-(const date & left, int n)
{
    return left + (-n);
}

int operator-(const date & left, const date & right)
{
    int res = 0;
    date right1(right);
    while (left > right1)
    {
        ++right1;
        ++res;
    }
    while (left < right1)
    {
        --right1;
        --res;
    }
    return res;
}

ostream & operator << (ostream & out, date d)
{
    out << setw(2) << setfill('0') << d.day() << "."
        << setw(2) << setfill('0') << d.month() << "."
        << setw(4) << setfill('0') << d.year();
    return out;
}

istream & operator >> (istream & in, date & d)
{
    char c;
    in >> d.m_day >> c >> d.m_month >> c >> d.m_year;
    return in;
}


int date::date_counter = 0;

int main()
{
    date A;
    cin >> A;
    ++A;
    cout << A << endl;
}