開発環境
- OS X Mavericks - Apple, ときどきWindows 8.1 + Cygwin64, MinGW (OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- C++ (プログラミング言語)
- g++(コンパイラ)
C++実践プログラミング (スティーブ オウアルライン (著)、Steve Oualline (原著)、Steve Oualline(原著)、望月 康司(翻訳)、クイープ(翻訳) 、オライリー・ジャパン)のⅣ部(高度なプログラミング概念)の18章(演算子のオーバーロード)、18.6(プログラミング実習)、実習 18-5.を解いてみる。
その他参考書籍
- C++プログラミング入門 (グレゴリー サティア (著)、ダウグ ブラウン (著)、Gregory Satir (原著)、Doug Brown (原著)、望月 康司 (翻訳)、谷口 功 (翻訳)、オライリージャパン)
実習 18-5.
コード(BBEdit, Emacs)
my_date2.h
#ifndef __my_date2_h__ #define __my_date2_h__ #include <iostream> #include <iomanip> namespace my_date2 { const int DAYS_PER_MONTH[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; class date { private: int month; int day; int year; static bool is_leap (int year) { return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0) ? true: false; } public: date () { month = 1; day = 1; year = 0; } date (int m, int d, int y) { month = m; day = d; year = y; } // 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 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 << '/' << std::setw(2) << std::setfill('0') << d.year; return (out_file); } extern date operator + (const date& op1, const date& op2); extern date operator - (const date& op1, const date& op2); extern std::istream& operator >> (std::istream& in_file, date&d); } #endif /*__my_date2_h__*/
my_date2.cpp
#include <iostream> #include "my_date2.h" namespace my_date2 { date operator + (const date& op1, const date& op2) { int month = op1.month + op2.month; int day = op1.day + op2.day; int year = op1.year + op2.year; while (month > 12 || day > DAYS_PER_MONTH[month - 1]) { if (month > 12) { month -= 12; ++year; } else { if (month == 2 && date::is_leap(year)) { if (day == 29) break; day -= 29; } else day -= DAYS_PER_MONTH[month - 1]; ++month; } } return date(month, day, year); } date operator - (const date& op1, const date& op2) { int year = op1.year - op2.year; int month = op1.month - op2.month; int day = op1.day - op2.day; if (month < 1) { month += 12; --year; } while (!(day > 0 && day <= DAYS_PER_MONTH[month - 1])) { if (date::is_leap(year)) { if (!(day > 0)) { if (month == 3) day += 29; else day += DAYS_PER_MONTH[month - 2]; --month; } else { if (month == 2) { if (day == 29) break; day -= 29; } else day -= DAYS_PER_MONTH[month - 1]; ++month; } } else { if (!(day > 0)) { day += DAYS_PER_MONTH[month - 2]; --month; } else { day -= DAYS_PER_MONTH[month - 1]; ++month; } } if (month < 1) { month += 12; --year; } } return date(month, day, year); } std::istream& operator >> (std::istream& in_file, date& d) { int month; int day; int year; char ch; month = 1; day = 1; year = 0; 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); in_file >> ch; if (in_file.fail()) return (in_file); if (ch != '/') { in_file.setstate(std::ios::failbit); return (in_file); } in_file >> year; if (in_file.fail()) return (in_file); d.month = month; d.day = day; d.year = year; } else in_file.setstate(std::ios::failbit); return (in_file); } }
test_my_date2.cpp
#include <iostream> #include "my_date2.h" int main(int argc, char *argv[]) { my_date2::date d0; my_date2::date d1(4, 1, 0); my_date2::date d2(12, 31, 0); my_date2::date d3; std::cout << d0 << "(01/01/00)\n"; std::cout << d1 << "(04/01/00)\n"; std::cout << d2 << "(12/31/00)\n"; std::cout << "日付を入力(MM/DD/YY) >> "; 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
CC=g++ CFLAGS=-g -Wall all: test_my_date2 test_my_date2: test_my_date2.cpp my_date2.o ${CC} ${CFLAGS} -o test_my_date2 test_my_date2.cpp my_date2.o my_date2.o: my_date2.cpp my_date2.h ${CC} -c -o my_date2.o my_date2.cpp clean: rm test_my_date2
入出力結果(Terminal)
$ make && ./test_my_date2 make && ./test_my_date2 g++ -c -o my_date2.o my_date2.cpp g++ -g -Wall -o test_my_date2 test_my_date2.cpp my_date2.o 01/01/00(01/01/00) 04/01/00(04/01/00) 12/31/00(12/31/00) 日付を入力(MM/DD/YY) >> 1/29/3 1/29/3 01/29/03 01/01/00 + 04/01/00 = 05/02/00 04/01/00 + 01/01/00 = 05/02/00 04/01/00 + 12/31/00 = 05/02/01 12/31/00 + 04/01/00 = 05/02/01 12/31/00 + 01/29/03 = 02/29/04 01/29/03 + 12/31/00 = 02/29/04 01/01/00 - 04/01/00 = 08/31/-1 04/01/00 - 01/01/00 = 02/29/00 04/01/00 - 12/31/00 = 03/01/-1 12/31/00 - 04/01/00 = 08/30/00 12/31/00 - 01/29/03 = 11/02/-3 01/29/03 - 12/31/00 = 12/30/01 $
0 コメント:
コメントを投稿