アフィリエイト広告を利用しています

広告

posted by fanblog

2017年11月11日

《その115》 復習用プログラム


 新版明解C++中級編には、静的メンバ,コンストラクタ,演算子の多重定義,フレンド関数などの復習用に、日付クラス Date.h が載っていますが、
その日付クラス Date.h のヘッダ部とソース部を下に記載します。

 ヘッダ部 Date.h,ソース部 Date.cpp のうち、Date.cppについては少し変更してあります。
新版明解C++中級編では、説明のために、同じようなコードが重複していたりする部分があるので、そこを書き換えるなどしました。

 主な変更点は次の3箇所です。

◆ 変更点(1)
テキストでは、
・1970/1/1からの経過日数を求める Date::operator long() const;

・日付の差を求める long Date::operator-(const Date& day) const;
を利用していますが、

このプログラムでは、逆に、
・long Date::operator-(const Date& day) const;

・Date::operator long() const;
を利用するように変更しました。
そのほうが、プログラムが単純になります。

◆ 変更点(2)
テキストでは、
・日付を 1日進める Date& Date::operator++();

・日付を dn日進める Date& Date::operator+=(int dn);

それぞれ独立したコードにしていますが、

同じような処理が多く含まれているので、
・Date& Date::operator++();

・Date& Date::operator+=(int dn);
を利用するように変更しました。
そのほうが、プログラムが単純になります。

◆ 変更点(3)
テキストでは、
bool Date::operator>(const Date& day) const;
bool Date::operator<(const Date& day) const;

・y, m, d の値を比較して結果を求めていますが、
このプログラムでは、
・Date::operator long() const; の返却値を比較して
求めています。
そのほうが、プログラムが単純になります。


 以下が、日付クラス Date.h のヘッダ部とソース部です。

// Date.h
#ifndef ___Class_Date
#define ___Class_Date

#include <string>
#include <iostream>

class Date {
int y;
int m;
int d;
static int dmax[];
static int days_of_year(int year);
static int days_of_month(int year, int month);

public:
static bool leap_year(int year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}

Date();
Date(int yy, int mm = 1, int dd = 1);

bool leap_year() const { return leap_year(y); }

int year() const { return y; }
int month() const { return m; }
int day() const { return d; }

void set_year(int yy) { y = yy; }
void set_month(int mm) { m = mm; }
void set_day(int dd) { d = dd; };
void set(int yy, int mm, int dd);

Date preceding_day() const;
Date following_day() const;

int day_of_year() const;
int day_of_week() const;
operator long() const;

Date& operator++();
Date operator++(int);
Date& operator--();
Date operator--(int);

Date& operator+=(int dn);
Date& operator-=(int dn);

Date operator+(int dn) const;
Date operator-(int dn) const;

friend Date operator+(int dn, const Date& day);

long operator-(const Date& day) const;

bool operator==(const Date& day) const;
bool operator!=(const Date& day) const;

bool operator> (const Date& day) const;
bool operator>=(const Date& day) const;
bool operator< (const Date& day) const;
bool operator<=(const Date& day) const;

std::string to_string() const;
};

std::ostream& operator<<(std::ostream& s, const Date& x);
std::istream& operator>>(std::istream& s, Date& x);

#endif


// Date.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <ctime>
#include <sstream>
#include <iostream>
#include "Date.h"

using namespace std;

int Date::dmax[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int Date::days_of_year(int year) { return 365 + leap_year(year); }
int Date::days_of_month(int year, int month) {
return dmax[month - 1] + (month == 2 && leap_year(year));
}

Date::Date() {
time_t current = time(NULL);
struct tm* local = localtime(&current);
y = local->tm_year + 1900;
m = local->tm_mon + 1;
d = local->tm_mday;
}
Date::Date(int yy, int mm, int dd) : y(yy), m(mm), d(dd) { }

void Date::set(int yy, int mm, int dd) {
y = yy; m = mm; d = dd;
}

Date Date::preceding_day() const {
Date temp(*this); return --temp;
}

Date Date::following_day() const {
Date temp(*this); return ++temp;
}

int Date::day_of_year() const { // 該当年内の経過日数
int days = d;
for (int i = 1; i < m; i++)
days += days_of_month(y, i);
return days;
}

int Date::day_of_week() const { // 曜日(0〜6)
int yy = y; int mm = m;
if (mm == 1 || mm == 2) { yy--; mm += 12; }
return (yy + yy / 4 - yy / 100 + yy / 400 + (13 * mm + 8) / 5 + d) % 7;
}

Date::operator long() const { // 変換関数(1970/1/1からの日数)
long dys = 0;
for (int i = 1970; i < y; i++)
dys += days_of_year(i);
return dys + day_of_year() - 1;
}


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


Date Date::operator++(int) { // 後置++
Date temp(*this);
*this += 1;
return temp;
}

Date& Date::operator--() { // 前置--
return *this -= 1;
}


Date Date::operator--(int) { // 後置--
Date temp(*this);
*this -= 1;
return temp;
}

Date& Date::operator+=(int dn) { // 日付を dn日進める。
if (dn < 0)
return *this -= -dn;
d += dn;
while (d > days_of_month(y, m)) {
d -= days_of_month(y, m);
if (++m > 12) {
y++; m = 1;
}
}
return *this;
}

Date& Date::operator-=(int dn) { // 日付を dn日戻す。
if (dn < 0)
return *this += -dn;
d -= dn;
while (d < 1) {
if (--m < 1) {
y--; m = 12;
}
d += days_of_month(y, m);
}
return *this;
}

Date Date::operator+(int dn) const { // dn日後を求める。
Date temp(*this);
return temp += dn;
}

Date Date::operator-(int dn) const { // dn日前を求める。
Date temp(*this);
return temp -= dn;
}

Date operator+(int dn, const Date& day) { // dayのdn日後を求める。
return day + dn;
}

long Date::operator-(const Date& day) const { // 日付の差
return long(*this) - long(day);
}


bool Date::operator==(const Date& day) const {
return y == day.y && m == day.m && d == day.d;
}

bool Date::operator!=(const Date& day) const {
return !(*this == day);
}

bool Date::operator>(const Date& day) const {
return long(*this) - long(day) > 0 ? true : false;
}


bool Date::operator>=(const Date& day) const {
return !(*this < day);
}

bool Date::operator<(const Date& day) const {
return long(*this) - long(day) < 0 ? true : false;
}


bool Date::operator<=(const Date& day) const {
return !(*this > day);
}

string Date::to_string() const {
ostringstream s;
s << y << "年" << m << "月" << d << "日";
return s.str();
}

ostream& operator<<(ostream& s, const Date& x) {
return s << x.to_string();
}

istream& operator>>(istream& s, Date& x) {
int yy, mm, dd; char c;
s >> yy >> c >> mm >> c >> dd;
x = Date(yy, mm, dd);
return s;
}



新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)






この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
https://fanblogs.jp/tb/6955000
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2018年08月 >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。