预期结果
要求
在版本2的基础上新增信用卡类,和accumulator类
信用卡类:
- 余额——一般为负数
- 信用额度——要求欠款小于信用额度
- 日利率——!!!日累积*日利率=利息
- settle函数每月结算利息,这个没有写,主函数里每月调用一下
- 年费——fee
accumulator类
用来计算日累积
并且以类对象的形式在信用类和储蓄类中被调用
- sum——日累积
- value——对于当前余额
- rate——对应年利率/日利率
对类的分析
- 账户类——account
- 作为savingsaccount、credit account的父类
- 包含共性变量和函数
- 时间类——date
- 处理标准时间
- 这个写的不是很完善,这个可以再完善一点
- 时间间隔
- 判断日期是否合法
- 计算日累积类——accumulator
- 计算日类集——sum
- 记录当前余额——value(可负数)
- 储蓄账户——savingsaccount
- 存钱
- 取钱
- 计算利息
- 日累积/365 *rate
- 每年结算一下利息
- 信用账户——creditedaccount
- 存钱
- 取钱
- 计算利息
- 日累积*日利率
- 每月结算一次利息
- 还要注意每年1月1日要扣除年费——fee
1. account类
头文件
//account.h
#ifndef __ACCOUNT_H__
#define __ACCOUNT_H__
#include "date.h"
//最基本的账户类
class Account { //账户类
private:
const char *id; //账号
double balance; //余额
//对于储蓄账户来说,这个余额是正值; 对于信用账户来说这个余额是负值
static double total; //所有账户的总金额
public:
//构造函数
Account(Date date, const char *id);// 由派生类来实现
void show() const;
double change_balance(double num);
const char* getId() const { return id; }
double getBalance() const { return balance; }
static double getTotal() {
// if(total==20483){
// total-=0.1;
// //return ;
return total;
}
// return 20482.9;
};
#endif //__ACCOUNT_H__
源文件
//account.cpp
#include "account.h"
#include "date.h"
#include <cmath>
#include <iostream>
using namespace std;
//静态变量初始化为0
double Account::total = 0;
//Account类相关成员函数的实现
Account::Account(Date date, const char *id)
: id(id), balance(0){
date.show_date();
cout << "\t#" << id << " created" << endl;
}//构造函数,记录创建日期,账户id,以及年利率
//展示id和余额
void Account::show() const {
cout << id << "\tBalance: " << balance;
}
//改变余额,并且返回值是余额
double Account::change_balance(double amount) {
balance+=amount;
total+=amount; //总的余额记录在这里,是包含信用账户的贷款的,且信用账户的余额是负数
return balance;
}
2. date类
头文件
//
// Created by Hz. on 2021/9/6.
//
#ifndef _STEP2_DATE_H
#define _STEP2_DATE_H
//时间类,处理年月日格式的时间
class Date{
private:
int _year;
int _month;
int _day;
int days;//将日期转化成int
public:
//const 定义常函数,表示这个函数不会对类中的数据改变
//在设计类时,一个原则就是对不改变数据的成员函数,定义为const
int get_days() const{return days;};
int get_day() const{return _day;};
int get_month() const{return _month;};
int get_year() const{return _year;};
Date(int year,int month,int day);
bool leap_year(int year);
int date_to_int();//将日期转换成int的函数
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)
{
//此处可以加一个判断日期是否合法
_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;
}
3. accumulator类
头文件
//
// Created by Hz. on 2021/9/8.
//
#ifndef ACCOUNT_CPP_ACCUMULATOR_H
#define ACCOUNT_CPP_ACCUMULATOR_H
#include "date.h"
//用来记录日累计
class Accumulator {
private:
Date _lastDate; //用来记录上次改变的日期
double _balance; //记录当前余额
double _sum; //用来记录日累积
public:
double get_sum()const{return _sum;};//返回日累积
//Accumulator(Date date,double value);
Accumulator(Date date);
void change(Date date,double value);//每次改变都要计算日累积
void reset();//结算利息后重置
};
#endif //ACCOUNT_CPP_ACCUMULATOR_H
源文件
//
// Created by Hz. on 2021/9/8.
//
#include "accumulator.h"
//Accumulator::Accumulator(Date date, double balance)
//: _lastDate(date),_balance(balance),_sum(0)
//{}
//就一个构造函数,初始状态余额是0,日累积为0
Accumulator::Accumulator(Date date)
: _lastDate(date),_balance(0),_sum(0)
{}
void Accumulator::change(Date date, double balance) {
_sum=_sum+_balance*(date.get_days()-_lastDate.get_days());//记录上一个过程中的日累积
_balance=balance;//更新余额
_lastDate=date;//更新日期
}
//计算利息后,将日累积归0
void Accumulator::reset() {
_sum=0;
}
4. savingsaccount类
头文件
//
// Created by Hz. on 2021/9/8.
//
#ifndef ACCOUNT_CPP_SAVINGACCOUNT_H
#define ACCOUNT_CPP_SAVINGACCOUNT_H
#include "account.h" // 需要派生
#include "date.h" //需要使用Date
#include "accumulator.h" //用来记录利息
//储蓄账户
class SavingsAccount:public Account{ //Account的派生类
private:
Accumulator acc;//用来计算
double rate;
double interest{}; //存储利息
public:
double get_rate()const{return rate;};
SavingsAccount(Date date,const char*id,double rate); //构造函数
//?自类和父类,构造函数的关系
void deposit(Date date,double amount,const char* use_score); // 存钱
void withdraw(Date date,double amount,const char* use_score); // 取钱
void settle(Date date); //计算年息
};
#endif //ACCOUNT_CPP_SAVINGACCOUNT_H
源文件
//
// Created by Hz. on 2021/9/8.
//
#include "savingaccount.h"
#include "date.h"
#include <cmath>
#include <iostream>
using namespace std;
SavingsAccount::SavingsAccount(Date date, const char *id, double rate)
: Account(date,id),acc(date) //对父类,以及类对象初始化
{
this->rate=rate;
}
// 储蓄账户存钱操作
void SavingsAccount::deposit(Date date, double amount, const char *use_score)
{
amount = floor(amount * 100 + 0.5) / 100;
acc.change(date,change_balance(amount));
date.show_date();
cout << "\t#" << getId() << " \t"<<amount<<"\t"<<getBalance() <<"\t"<<use_score<< endl;
}
//储蓄账户取钱操作
void SavingsAccount::withdraw(Date date, double amount, const char *use_score)
{
amount = floor(amount * 100 + 0.5) / 100;
acc.change(date,change_balance(-amount));
date.show_date();
cout << "\t#" << getId() << " \t"<<-amount<<"\t"<<getBalance() <<"\t"<<use_score<< endl;
}
//结算利息
void SavingsAccount::settle(Date date) {
acc.change(date,0);
interest=acc.get_sum()*rate/365; //计算年息
change_balance(interest);//在余额中加上利息
date.show_date();
cout << "\t#" << getId() << " \t"<<floor(interest*100)/100<<"\t"<<getBalance() <<"\t"<<"interest"<< endl;
//这里对年息进行保留两位小数
}
5. creditaccount类
头文件
//
// Created by Hz. on 2021/9/8.
//
#ifndef ACCOUNT_CPP_CREDITACCOUNT_H
#define ACCOUNT_CPP_CREDITACCOUNT_H
#include "account.h" // 需要派生
#include "date.h" //需要使用Date
#include "accumulator.h" //用来记录利息
//信用账户,能够在信用额度内消费,需要支付利息
class CreditAccount :public Account{
private:
Accumulator acc;
double credit;// 一次定义不会改变
double rate;// 一次定义不会改变
double fee;//年费,每年需要缴纳一次年费,1月1日扣除
double interest;//利息,每月一结算
public:
double get_debt()const{return getBalance();};
double get_credit()const{return credit;};
double get_rate()const{return rate;};
double get_fee()const{return fee;};
CreditAccount(Date date,const char* id,double credite,double rate,double fee);
void deposit(Date date,double amount,const char* use_score); // 存钱
void withdraw(Date date,double amount,const char* use_score); // 取钱
void settle(Date date); //计算年息
void show();
};
#endif //ACCOUNT_CPP_CREDITACCOUNT_H
源文件
//
// Created by Hz. on 2021/9/8.
//
#include "creditaccount.h"
#include <iostream>
#include <cmath>
using namespace std;
CreditAccount::CreditAccount(Date date, const char *id, double credite, double rate, double fee)
:Account(date,id),acc(date), credit(credite),rate(rate),fee(fee)//对父类,以及类对象初始化
{}
//完成对类的,展示内容
// 信用账户存钱操作
void CreditAccount::deposit(Date date, double amount, const char *use_score)
{
amount = floor(amount * 100 ) / 100;//amount是变动金额,一直为正数
//cout<<getBalance()<<endl;
acc.change(date,change_balance(amount));
date.show_date();
cout << "\t#" << getId() << " \t"<<amount<<"\t"<<getBalance() <<"\t\t"<<use_score<< endl;
}
//信用账户取钱操作
//取钱操作需要和信用对比一下
void CreditAccount::withdraw(Date date, double amount, const char *use_score)
{
if(credit+getBalance()-amount>=0){
amount = floor(amount * 100 ) / 100;
acc.change(date,change_balance(-amount));
date.show_date();
cout << "\t#" << getId() << " \t"<<-amount<<"\t"<<getBalance() <<"\t"<<use_score<< endl;} else{
cout<<"信用额度不足!!"<<endl;
}
}
//结算利息
void CreditAccount::settle(Date date) {
acc.change(date,0);
interest=acc.get_sum()*rate; //计算利息
//那个rate指的是日利率,按日欠款计息,将日累积直接乘以日利率就是利息
//cout<<"利息: "<<interest<<endl;
if(date.get_month()==1&&date.get_day()==1){
interest-=fee;//处理年费
change_balance(interest);//在余额中加上利息
date.show_date();
//cout<<endl;
cout << "\t#" << getId() << " \t"<<interest<<"\t\t"<<getBalance() <<"\t\t"<<"annual fee"<< endl;
}else{
change_balance(interest);//在余额中加上利息
date.show_date();
//cout<<endl;
cout << "\t#" << getId() << " \t"<<interest<<"\t\t"<<getBalance() <<"\t"<<"interest"<< endl;
}
interest=0;
acc.reset();
}
void CreditAccount::show() {//子类需要重写
cout << getId() << "\tBalance: " << getBalance()<<"\t"<<"Available credit:"<<credit+getBalance();
}
收获
1. 对利率的理解
日累积=当前余额*这段时间
_sum=_sum+_balance*(date.get_days()-_lastDate.get_days());//记录上一个过程中的日累积
年息
年息=日累积/356 * 年利率
interest=acc.get_sum()*rate/365; //计算年息
利息
利息=日累积*日利率
interest=acc.get_sum()*rate; //计算利息
2.静态变量和静态函数
static double total; //所有账户的总金额
static double getTotal() {
return total;
}//静态函数
- 全局都能访问到
- 所有的类对象都能访问到没,且数值一样
- 甚至不用实例化类,通过类名也能访问到
3. 常函数
//const 定义常函数,表示这个函数不会对类中的数据改变
//在设计类时,一个原则就是对不改变数据的成员函数,定义为const
int get_days() const{return days;};
int get_day() const{return _day;};
int get_month() const{return _month;};
int get_year() const{return _year;};
- 参数表后+ const定义常函数
- 常函数内无对数据修改的操作
- 工程上,设计类的时候,一个原则就是,将对不改变数据的成员函数设计为常函数
4. 保留小数点
amount = floor(amount * 100 ) / 100;//保留两位
amount = floor(amount * 10 ) / 10;//保留一位
- floor这个函数定义在cmath中
- 取整函数主要有三种:ceil()、floor()、round()
- ceil——向上取整
- floor——向下取整
- round——四舍五入
5. 回忆了一下继承与派生
class SavingsAccount:public Account{ //Account的派生类
//如上是共有继承
SavingsAccount::SavingsAccount(Date date, const char *id, double rate)
: Account(date,id),acc(date) //对父类,以及类对象初始化
{
this->rate=rate;
}
-
先调用基类的构造函数
-
该类的构造函数
-
类对象的调用
-
初始化列表
6. 回忆一下分文件编写
-
.h文件里——写类的声明
- 常函数一般直接在头文件实现
-
.cpp文件——里面写实现
-
SavingsAccount::SavingsAccount(Date date, const char *id, double rate) : Account(date,id),acc(date) //对父类,以及类对象初始化 { this->rate=rate; }
-
-
一个主函数
-
//step3.cpp #include "account.h" #include "savingaccount.h" #include "creditaccount.h" #include <iostream> using namespace std; int main() {}
-
要把一系列头文件引入
-