Читаем Программирование. Принципы и практика использования C++ Исправленное издание полностью

#include "Chrono.h"


namespace Chrono {

class Date {

public:

  enum Month {

    jan=1, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec

  };


class Invalid { }; // для генерации в виде исключения


Date(int y, Month m, int d); // проверка и инициализация даты

  Date;                    // конструктор по умолчанию

                             // операции копирования по умолчанию

                             // в порядке


  // немодифицирующие операции:

  int day const { return d; }

  Month month const { return m; }

  int year const { return y; }


  // модифицирующие операции:

  void add_day(int n);

  void add_month(int n);

  void add_year(int n);

private:

  int y;

  Month m;

  int d;

};


bool is_date(int y, Date::Month m, int d); // true для корректных дат


bool leapyear(int y); // true, если y — високосный год


bool operator==(const Date& a, const Date& b);

bool operator!=(const Date& a, const Date& b);


ostream& operator<<(ostream& os, const Date& d);

istream& operator>>(istream& is, Date& dd);

} // Chrono


Определения находятся в файле Chrono.cpp.


// Chrono.cpp

namespace Chrono {

// определения функций-членов:

  Date::Date(int yy, Month mm, int dd)

       :y(yy), m(mm), d(dd)

  {

    if (!is_date(yy,mm,dd)) throw Invalid;

  }


  Date& default_date

  {

    static Date dd(2001,Date::jan,1); // начало XXI века

    return dd;

  }


  Date::Date

       :y(default_date.year),

        m(default_date.month),

        d(default_date.day)

  {

  }


  void Date:: add_day(int n)

  {

    // ...

  }


  void Date::add_month(int n)

  {

    // ...

  }


  void Date::add_year(int n)

  {

    if (m==feb && d==29 && !leapyear(y+n)) { // помните о високосных годах!

      m = mar; // 1 марта вместо

               // 29 февраля

      d = 1;

    }

    y+=n;

  }


  // вспомогательные функции:

  bool is_date(int y, Date::Month m, int d)

  {

    // допустим, что y — корректный объект

    if (d<=0) return false; // d должна быть положительной

    if (m < Date::jan || Date::dec < m) return false;

    int days_in_month = 31; // большинство месяцев состоит из 31 дня

    switch (m) {

    case Date::feb: // продолжительность февраля варьирует

      days_in_month = (leapyear(y)) ? 29:28;

      break;

    case Date::apr: case Date::jun: case Date::sep: case

      Date::nov:

      days_in_month = 30; // остальные месяцы состоят из 30 дней

      break;

    }

    if (days_in_month

    return true;

  }


  bool leapyear(int y)

  {

    // см. упражнение 10

  }


  bool operator==(const Date& a, const Date& b)

  {

    return a.year==b.year

      && a.month==b.month

      && a.day==b.day; 

  }


  bool operator!=(const Date& a, const Date& b)

  {

    return !(a==b);

  }


  ostream& operator<<(ostream& os, const Date& d)

  {

    return os << '(' << d.year

      << ',' << d.month

      << ',' << d.day << ')';

  }


  istream& operator>>(istream& is, Date& dd)

  {

    int y, m, d;

    char ch1, ch2, ch3, ch4;

    is >> ch1 >> y >> ch2 >> m >> ch3 >> d >> ch4;

    if (!is) return is;

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже