2014年4月16日水曜日

開発環境

C++実践プログラミング (スティーブ オウアルライン (著)、Steve Oualline (原著)、Steve Oualline(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅣ部(高度なプログラミング概念)の18章(演算子のオーバーロード)、18.6(プログラミング実習)、実習 18-4.を解いてみる。

その他参考書籍

実習 18-4.

コード(BBEdit, Emacs)

my_date.h

#ifndef __my_date_h__
#define __my_date_h__
#include <iostream>
#include <iomanip>

namespace my_date {
  const int DAYS_PER_MONTH[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  class date {
  private:
    int month;
    int day;
  public:
    date () {
      month = 1;
      day = 1;
    }
    date (const int m, const int d) {
      month = m;
      day = d;
    }
    // date (const date& old_date);
    // ~date () {}
    // date operator = (const date& old_date);

    date operator += (const date& op2) {
      return (*this) + op2;
    }

    date operator -= (const date& op2) {
      return (*this) - op2;
    }

    friend date operator + (const date& op1, const date& op2);
    friend date operator - (const date& op1, const date& op2);
    friend std::ostream& operator << (std::ostream& out_file, const date& d);
    friend std::istream& operator >> (std::istream& in_file, date& d);
  };

  inline date operator + (const date& op1, const date& op2)
  {
    int m = op1.month + op2.month;
    int d = op1.day + op2.day;

    m = m > 12 ? m - 12 : m;
    while (d > DAYS_PER_MONTH[m - 1]) {
      d -= DAYS_PER_MONTH[m - 1];
      ++m;
      m = m > 12 ? m - 12 : m;
    }
    return date(m, d);
  }

  inline date operator - (const date& op1, const date& op2)
  {
    int m = op1.month - op2.month;
    int d = op1.day - op2.day;
    
    m = m < 1 ? 12 + m : m;
    while (!(d > 0 && d <= DAYS_PER_MONTH[m - 1])) {
      d += DAYS_PER_MONTH[m - 2];
      --m;
      m = m < 1 ? 12 + m : m;
    }
    return date(m, d);
  }

  inline std::ostream& operator << (std::ostream& out_file, const date& d)
  {
    out_file << std::setw(2) << std::setfill('0') << d.month << '/' <<
      std::setw(2) << std::setfill('0') << d.day;
    return (out_file);
  }

  extern std::istream& operator >> (std::istream& in_file, date& d);
}
#endif /*__my_date_h__*/

my_date.cpp

#include <iostream>

#include "my_date.h"

namespace my_date {
  std::istream& operator >> (std::istream& in_file, date& d)
  {
    int month = 1;
    int day = 1;
    char ch;

    std::istream::sentry the_sentry(in_file, true);

    if (the_sentry) {
      if (in_file.fail()) return (in_file);
      
      in_file >> month;
      if (in_file.fail()) return (in_file);

      in_file >> ch;
      if(in_file.fail()) return (in_file);
      if (ch != '/') {
        in_file.setstate(std::ios::failbit);
        return (in_file);
      }

      in_file >> day;
      if (in_file.fail()) return (in_file);

      d.month = month;
      d.day = day;
    }
    else
      in_file.setstate(std::ios::failbit);
    return (in_file);
  }
}

test_my_date.cpp

#include <iostream>

#include "my_date.h"

int main(int argc, char *argv[])
{
  my_date::date d0;
  my_date::date d1(4, 1);
  my_date::date d2(12, 31);
  my_date::date d3;

  std::cout << d0 << "(01/01)\n";
  std::cout << d1 << "(04/01)\n";
  std::cout << d2 << "(12/31)\n";

  std::cout << "日付を入力(月/日) >> ";
  std::cin >> d3;
  std::cout << d3 << '\n';

  std::cout << d0 << " + " << d1 << " = " << d0 + d1 << std::endl;
  std::cout << d1 << " + " << d0 << " = " << d1 + d0 << std::endl;
  std::cout << d1 << " + " << d2 << " = " << d1 + d2 << std::endl;
  std::cout << d2 << " + " << d1 << " = " << d2 + d1 << std::endl;
  std::cout << d2 << " + " << d3 << " = " << d2 + d3 << std::endl;
  std::cout << d3 << " + " << d2 << " = " << d3 + d2 << std::endl;

  std::cout << d0 << " - " << d1 << " = " << d0 - d1 << std::endl;
  std::cout << d1 << " - " << d0 << " = " << d1 - d0 << std::endl;
  std::cout << d1 << " - " << d2 << " = " << d1 - d2 << std::endl;
  std::cout << d2 << " - " << d1 << " = " << d2 - d1 << std::endl;
  std::cout << d2 << " - " << d3 << " = " << d2 - d3 << std::endl;
  std::cout << d3 << " - " << d2 << " = " << d3 - d2 << std::endl;

  return (0);
}

Makefile

#
# FSFのg++コンパイラ用のMakefile
#
CC=g++
CFLAGS=-g -Wall
all: test_my_date

test_my_date: test_my_date.o my_date.o
 ${CC} ${CFLAGS} -o test_my_date test_my_date.o my_date.o

test_my_date.o: test_my_date.cpp my_date.h
 ${CC} -c -o test_my_date.o test_my_date.cpp

my_date.o: my_date.cpp my_date.h
 ${CC} -c -o my_date.o my_date.cpp

clean:
 rm test_my_date

入出力結果(Terminal)

bash-4.3$ make && ./test_my_date
make && ./test_my_date
g++ -c -o test_my_date.o test_my_date.cpp
g++ -c -o my_date.o my_date.cpp
g++ -g -Wall -o test_my_date test_my_date.o my_date.o
01/01(01/01)
04/01(04/01)
12/31(12/31)
日付を入力(月/日) >> 5/6
5/6
05/06
01/01 + 04/01 = 05/02
04/01 + 01/01 = 05/02
04/01 + 12/31 = 05/02
12/31 + 04/01 = 05/02
12/31 + 05/06 = 06/06
05/06 + 12/31 = 06/06
01/01 - 04/01 = 08/31
04/01 - 01/01 = 02/28
04/01 - 12/31 = 03/01
12/31 - 04/01 = 08/30
12/31 - 05/06 = 07/25
05/06 - 12/31 = 04/05
bash-4.3$ 

0 コメント:

コメントを投稿