此次运用了继承,另将record函数设为protected函数,使得派生类处理每一笔具体账目时可以调用该函数来改变余额并输出账目信息。
//date.h
#ifndef _DATE_H_
#define _DATE_H_
class Date//日期类
{
private:
int year;
int month;
int day;
int totalDays;//该日期是从公元元年1曰1日开始的第几天
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
#include
using namespace std;
namespace
{ //namespace使下面的定义只在当前文件中有效
//存储平年中的某个月1日之前有多少天,为便于getMaxDay函数的实现,该数组多出一项
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<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<value=value;
}
//初始化,将日期变为date,数值变为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
#include
using namespace std;
class Account //账户类
{
private:
string id;//账号
double balance;//余额
static double total;//所有账户的总金额
protected:
//供派生类调用的构造函数,id为账户
Account(const Date &date,const string &id);
//记录一笔账,日期,金额,说明
void record(const Date &date,double amount,const string &desc);
//报告错误信息
void error(const string &msg)const;
public:
const string &getID()const{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 string &id,double rate);//构造函数
double getRate()const{return rate;}
void deposit(const Date &date,double amount,const string &desc);//存入现金
void withdraw(const Date &date,double dmount,const string &desc);//取出现金
void settle(const Date &date);//结算利息,每年1月1日调用一次该函数
};
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 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 string &desc);//存入现金
void withdraw(const Date &date,double dmount,const string &desc);//取出现金
void settle(const Date &date);//结算利息和年费,每月1日调用一次该函数
void show()const;
};
#endif
//account.cpp
#include"account.h"
#include
#include
using namespace std;
double Account::total=0;
Account::Account(const Date &date,const string &id):id(id),balance(0)
{
date.show();
cout<<"\t#"<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,"interest");
acc.reset(date,getBalance());
}
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 money");
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<<"\tAvailable credit:"<
using namespace std;
int main()
{
Date date(2018,11,1);//起始日期
//建立几个账户
SavingsAccount sa1(date,"s3755217",0.015);
SavingsAccount sa2(date,"02342342",0.015);
CreditAccount ca(date,"C5392394",10000,0.0005,50);
//11月的账目
sa1.deposit(Date(2018,11,5),5000,"salary");
ca.withdraw(Date(2018,11,15),2000,"buy a cell");
sa2.deposit(Date(2018,11,25),10000,"sell stock 0323");
//结算信用卡
ca.settle(Date(2018,12,1));
//12月账目
ca.deposit(Date(2018,12,1),2016,"repay the credit");
sa1.deposit(Date(2018,12,5),5500,"salary");
//结算所有账户
sa1.settle(Date(2019,1,1));
sa2.settle(Date(2019,1,1));
ca.settle(Date(2019,1,1));
cout<