前言
在第一版中,时间是由单纯的int类型的天数来操作的。
对用户十分不友好,因此新添加了时间类,将时间转换成年月日
账户类
//account.h
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
#include "date.h"
class SavingsAccount { //储蓄账户类
private:
const char *id; //账号
const char *source; //记录用途
double balance; //余额
double rate; //存款的年利率
int lastDate; //上次变更余额的时期
double accumulation; //余额按日累加之和
static double total; //所有账户的总金额
//使用静态变量来记录所有账户的余额
//记录一笔帐,date为日期,amount为金额,desc为说明
void record(Date date, double amount);
//获得到指定日期为止的存款金额按日累积值
double accumulate(Date date) const {
return accumulation + balance * (date.get_days() - lastDate);//返回的是存款按日累计值,40*5000+45*10500
}
public:
//构造函数
SavingsAccount(Date date, const char *id, double rate);
const char* getId() const { return id; }
double getBalance() const { return balance; }
double getRate() const { return rate; }
static double getTotal() { return total; }
//存入现金
void deposit(Date date, double amount,const char *m_source);
//取出现金
void withdraw(Date date, double amount,const char *m_source);
//结算利息,每年1月1日调用一次该函数
void settle(Date date);
//显示账户信息
void show() const;
};
#endif //__ACCOUNT_H__
//account.cpp
#include "account.h"
#include "date.h"
#include <cmath>
#include <iostream>
using namespace std;
//静态变量初始化为0
double SavingsAccount::total = 0;
//SavingsAccount类相关成员函数的实现
SavingsAccount::SavingsAccount(Date date, const char *id, double rate)
: id(id), balance(0), rate(rate), lastDate(date.get_days()), accumulation(0) {
date.show_date();
cout << "\t#" << id << " created" << endl;
}//构造函数,记录创建日期,账户id,以及年利率
void SavingsAccount::record(Date date, double amount) {
accumulation = accumulate(date);//记录此次动作之前的日累计和
lastDate = date.get_days();
amount = floor(amount * 100 + 0.5) / 100; //保留小数点后两位
balance += amount;//余额改变
total += amount;//总余额改变
//每次调用该函数会输出本次余额改变和当前余额
date.show_date();
cout << "\t#" << id << "\t" << amount << "\t" << balance << "\t"<<source<<endl;
}
void SavingsAccount::deposit(Date date, double amount,const char *m_source) {
source=m_source;
record(date, amount);
}
void SavingsAccount::withdraw(Date date, double amount,const char *m_source) {
source=m_source;
if (amount > getBalance())
cout << "Error: not enough money" << endl;
else
record(date, -amount);
}
//计算年息
void SavingsAccount::settle(Date date) {
double interest = accumulate(date) * rate / 365; //计算年息
if (interest != 0)
record(date, interest);
accumulation = 0;//日累计和归零
}
//展示id和余额
void SavingsAccount::show() const {
cout << id << "\tBalance: " << balance;
}
时间类
//
// Created by Hz. on 2021/9/6.
//
#ifndef _STEP2_DATE_H
#define _STEP2_DATE_H
class Date{
public:
int _year;
int _month;
int _day;
int days;
Date(int year,int month,int day);
bool leap_year(int year);
int date_to_int();
int get_days();
void show_date();
};
#endif //_STEP2_DATE_H
//
// Created by Hz. on 2021/9/6.
//
#include "date.h"
#include <cmath>
#include <iostream>
using namespace std;
//初始化,并且判断输入的时间格式是否正确
Date::Date(int year, int month, int day)
{
// 不健全的日期合法判断
// int month_length[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};
// if ((year >= 0)
// && (month >= 1 && month <= 12)
// && (day >= 1 && day <= month_length[month-1]))
// //当前年月日合法,可以进行初始化
// _year = year;
// _month = month;
// _day = day;
// }else {
// //当前月不合法,进行初始化
// cout << "传入的参数不合法" << endl;
// }
_year = year;
_month = month;
_day = day;
date_to_int();
}
//展示时间信息
void Date::show_date() {
cout<<_year<<"-"<<_month<<"-"<<_day;
}
//判断是否闰年
bool Date::leap_year(int year) {
return ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0));
}
//将日期转换成数字
//与1971年的1月1日相比,暴力求,此处可以优化
int Date::date_to_int(){
int year=_year;
int month=_month;
int day=_day;
int month_length[] = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};
int ans = 0;
while (year != 1971 or month != 1 or day != 1) {
++ans;
if (--day == 0)
if (--month == 0)
--year;
if (day == 0) {
day = month_length[month];
if (month == 2 && leap_year(year))
++day;
}
if (month == 0)
month = 12;
}
days=ans;
return days;
}
int Date::get_days() {
return days;
}
主函数
//step_2.cpp
#include "account.h"
#include <iostream>
using namespace std;
int main() {
Date date(2008, 11, 1);//起始日期
//建立几个账户
SavingsAccount accounts[] = {
SavingsAccount(date, "S3755217", 0.015),
SavingsAccount(date, "02342342", 0.015)
};
//通过内存大小来计算账户数目
const int n = sizeof(accounts) / sizeof(SavingsAccount); //账户总数
//11月份的几笔账目
accounts[0].deposit(Date(2008, 11, 5), 5000, "salary");
accounts[1].deposit(Date(2008, 11, 25), 10000, "sell stock 0323");
//12月份的几笔账目
accounts[0].deposit(Date(2008, 12, 5), 5500, "salary");
accounts[1].withdraw(Date(2008, 12, 20), 4000, "buy a laptop");
//结算所有账户并输出各个账户信息
cout << endl;
for (int i = 0; i < n; i++) {
accounts[i].settle(Date(2009, 1, 1));
accounts[i].show();
cout << endl;
}
cout << "Total: " << SavingsAccount::getTotal() << endl;
return 0;
}
小结
总体思路与step1类似
account 银行账户的功能基本类似
构造函数——初始化
一系列get函数返回一个特定的值
买入
撤出
计算年息
展示
新增了静态变量static total
和返回这个变量的静态函数
这个静态变量和静态函数,全局都可以访问得到
!! 重点是引入时间类
时间类里面的重点是如何计算时间差
时间类:
变量:
全部是用int定义的
年、月、日、以及一个days,将日期转换成一个常数,方便计算日期差
函数:
初始化函数: 这里面有个判断时间是否合法可以详细写一下
leap_year 判断年份是不是闰年
date_to_int 参考了一道算法题,暴力求日期 !!!这个可以再琢磨一下
get_days 返回,将日期转换后的int
show_date 没什么好说,展示日期
修改的账户类:account
变量:
const char* 常量字符川
const char*id 记录了ID,ID变成了字符串类型
const char*source 记录了买入和卖出的原因
lastdate不变,仍旧是一个int类型,由date中的函数反向它
就是多了字符串,以及将日期的格式转换一下
小结:
const char*
日期判断是否合法
class 中的类成员和类对象可以全局访问,甚至不需要创建对象也能够访问
日期类计算时间差