//date.h
#ifndef __DATE_H__
#define __DATE_H__
class Date {
private:
int year;
int month;
int day;
int totalDays;
public:
Date(int year, int month, int day);
int getYear()const { return year; }
int getMonth()const { return month; }
int getDay()const { return day; }
int getMaxDay()const;//获得当月的天数
bool isLeapYear()const {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
void show() const;//输出当前日期
int distance(const Date &date)const {
return totalDays - date.totalDays;
}
};
#endif
//date.cpp
#include "date.h"
#include<iostream>
#include<cstdlib>
using namespace std;
namespace {
const int DAYS_BEFORE_MONTH[] = { 0,31,59,90,120,151,181,212,243,273,304,334,365 };
}
Date::Date(int year, int month, int day) : year(year), month(month), day(day) {
if (day <= 0 || day>getMaxDay()) {
cout << "invalid date: ";
show();
cout << endl;
exit(1);
}
int years = year - 1;
totalDays = years * 365 + years / 4 - years / 100 + years / 400 + DAYS_BEFORE_MONTH[month - 1] + day;
if (isLeapYear() && month>2)totalDays++;
}
int Date::getMaxDay()const {
if (isLeapYear() && month == 2)
return 29;
else
return DAYS_BEFORE_MONTH[month] - DAYS_BEFORE_MONTH[month - 1];
}
void Date::show() const {
cout << getYear() << "-" << getMonth() << "-" << getDay();
}
//accumulator.h
#ifndef __ACCUMUKLATOR_H__
#define __ACCUMUKLATOR_H__
#include"date.h"
class Accumulator {
private:
Date lastDate;
double value;
double sum;
//date为开始累加的日期
//lastDate为上次变更数值的日期
public:
Accumulator(const Date &date,double value):lastDate(date),value(value),sum(0){}
double getSum(const Date &date)const {
return sum + value*date.distance(lastDate);
}
//在date将数值变成value
void change(const Date &date, double value) {
sum = getSum(date);
lastDate = date;
this->value = value;
}
//初始化
void reset(const Date &date, double value) {
lastDate = date;
this->value = value;
sum = 0;
}
};
#endif
//account.h
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
#include"date.h"
#include"accumulator.h"
#include<string>
class Account {
private:
std::string id;
double balance;//余额
static double total;//所有账户总金额
protected:
Account(const Date &date, const std::string &id);
void record(const Date &date, double amount, const std::string &desc);
void error(const std::string &msg) const;
public:
const std::string &getID() { return id; }
double getBalance()const { return balance; }
static double getTotal() { return total; }
void show() const;
};
//储蓄账户
class SavingsAccount :public Account {
private:
Accumulator acc;
double rate;
public:
SavingsAccount(const Date &date, const std::string &id, double rate);
double getRate()const { return rate; }
void deposit(const Date &date, double amount, const std::string &desc);
void withdraw(const Date &date, double amount, const std::string &desc);
void settle(const Date &date);
};
//信用卡账户计算
class CreditAccount :public Account {
private:
Accumulator acc;//累加器
double credit;//信用额度
double rate;//欠款日利率
double fee;//信用卡年费
//欠款额
double getDebt()const {
double balance = getBalance();
return (balance < 0 ? balance : 0);
}
public:
CreditAccount(const Date &date, const std::string &id, double credit, double rate, double fee);
double getCredit()const { return credit; }
double getRate()const { return rate; }
double getFee()const { return fee; }
//获得可用信用额度
double getAvailableCredit()const {
if (getBalance() < 0)
return credit + getBalance();
else
return credit;
}
void deposit(const Date &date, double amount, const std::string &desc);
void withdraw(const Date &date, double amount, const std::string &desc);
void settle(const Date &date);
void show()const;
};
#endif
//account.cpp
#include"account.h"
#include<cmath>
#include<iostream>
using namespace std;
double Account::total = 0;
//account类
Account::Account(const Date &date, const string &id) :id(id), balance(0) {
date.show();
cout << "\t#" << id << " created" << endl;
}
void Account::record(const Date &date, double amount, const string &desc) {
amount = floor(amount * 100 + 0.5) / 100;
balance += amount;
total += amount;
date.show();
cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
}
void Account::show() const {
cout << id << "\tBalance: " << balance;
}
void Account::error(const string &msg)const {
cout << "Error(#" << id << "):" << msg << endl;
}
//SavingsAccount类
SavingsAccount::SavingsAccount(const Date &date,const string &id,double rate):Account(date,id),rate(rate),acc(date,0){}
void SavingsAccount::deposit(const Date &date, double amount, const string &desc) {
record(date, amount, desc);
acc.change(date, getBalance());
}
void SavingsAccount::withdraw(const Date &date,double amount,const string &desc){
if (amount > getBalance()) {
error("not enough money");
}
else {
record(date, -amount, desc);
acc.change(date, getBalance());
}
}
void SavingsAccount::settle(const Date &date) {
double interest = acc.getSum(date)*rate / date.distance(Date(date.getYear() - 1, 1, 1));
if (interest != 0)
record(date, interest, "interesr");
acc.reset(date, getBalance());
}
//creditaccount类
CreditAccount::CreditAccount(const Date &date, const string &id, double credit, double rate, double fee) :Account(date, id), credit(credit), rate(rate), fee(fee), acc(date, 0) {}
void CreditAccount::deposit(const Date &date, double amount, const string &desc) {
record(date, amount, desc);
acc.change(date, getDebt());
}
void CreditAccount::withdraw(const Date &date, double amount, const string &desc) {
if (amount - getBalance() > credit) {
error("not enough credit");
}
else
{
record(date, -amount, desc);
acc.change(date, getDebt());
}
}
void CreditAccount::settle(const Date &date) {
double interest = acc.getSum(date)*rate;
if (interest != 0)
record(date, interest, "interest");
if (date.getMonth() == 1)
record(date, -fee, "annual fee");
acc.reset(date, getDebt());
}
void CreditAccount::show()const {
Account::show();
cout << "\tAvaliable credit: " << getAvailableCredit();
}
//7_10
#include"account.h"
#include<cmath>
#include<iostream>
using namespace std;
double Account::total = 0;
//account类
Account::Account(const Date &date, const string &id) :id(id), balance(0) {
date.show();
cout << "\t#" << id << " created" << endl;
}
void Account::record(const Date &date, double amount, const string &desc) {
amount = floor(amount * 100 + 0.5) / 100;
balance += amount;
total += amount;
date.show();
cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t" << desc << endl;
}
void Account::show() const {
cout << id << "\tBalance: " << balance;
}
void Account::error(const string &msg)const {
cout << "Error(#" << id << "):" << msg << endl;
}
//SavingsAccount类
SavingsAccount::SavingsAccount(const Date &date,const string &id,double rate):Account(date,id),rate(rate),acc(date,0){}
void SavingsAccount::deposit(const Date &date, double amount, const string &desc) {
record(date, amount, desc);
acc.change(date, getBalance());
}
void SavingsAccount::withdraw(const Date &date,double amount,const string &desc){
if (amount > getBalance()) {
error("not enough money");
}
else {
record(date, -amount, desc);
acc.change(date, getBalance());
}
}
void SavingsAccount::settle(const Date &date) {
double interest = acc.getSum(date)*rate / date.distance(Date(date.getYear() - 1, 1, 1));
if (interest != 0)
record(date, interest, "interesr");
acc.reset(date, getBalance());
}
//creditaccount类
CreditAccount::CreditAccount(const Date &date, const string &id, double credit, double rate, double fee) :Account(date, id), credit(credit), rate(rate), fee(fee), acc(date, 0) {}
void CreditAccount::deposit(const Date &date, double amount, const string &desc) {
record(date, amount, desc);
acc.change(date, getDebt());
}
void CreditAccount::withdraw(const Date &date, double amount, const string &desc) {
if (amount - getBalance() > credit) {
error("not enough credit");
}
else
{
record(date, -amount, desc);
acc.change(date, getDebt());
}
}
void CreditAccount::settle(const Date &date) {
double interest = acc.getSum(date)*rate;
if (interest != 0)
record(date, interest, "interest");
if (date.getMonth() == 1)
record(date, -fee, "annual fee");
acc.reset(date, getDebt());
}
void CreditAccount::show()const {
Account::show();
cout << "\tAvaliable credit: " << getAvailableCredit();
}