Читаем Программирование полностью

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;

    if (ch1!='(' || ch2!=',' || ch3!=',' || ch4!=')') { // ошибка формата

      is.clear(ios_base::failbit); // установлен неправильный бит

      return is;

    }

    dd = Date(y, Date::Month(m),d); // обновляем dd

    return is;

  }

  enum Day {

    sunday, monday, tuesday, wednesday, thursday, friday, saturday

  };

  Day day_of_week(const Date& d)

  {

    // ...

  }

  Date next_Sunday(const Date& d)

  {

    // ...

  }

  Date next_weekday(const Date& d)

  {

    // ...

  }

} // Chrono 

Функции, реализующие операции >> и << для класса Date, будут подробно рассмотрены в разделах 10.7 и 10.8.

Задание

Это задание сводится к запуску последовательности версий класса Date. Для каждой версии определите объект класса Date с именем today, инициализированный датой 25 июня 1978 года. Затем определите объект класса Date с именем tomorrow и присвойте ему значение, скопировав в него объект today и увеличив его день на единицу с помощью функции add_day(). Выведите на печать объекты today и tomorrow, используя оператор <<, определенный так, как показано в разделе 9.8.

Проверка корректности даты может быть очень простой. В любом случае не допускайте, чтобы месяц выходил за пределы диапазона [1,12], а день месяца — за пределы диапазона [1,31]. Проверьте каждую версию хотя бы на одной некорректной дате, например (2009, 13, –5).

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