一、实验目的:
- 掌握动态联编的概念;
- 掌握虚函数和纯虚函数的使用方法;
- 掌握抽象类的使用。
二、实验内容:
在前面实验基础上,完成以下内容:
(1)在基类Account中添加deposit、withdraw、settle这3个函数的声明,且将它们都声明为纯虚函数,通过基类的指针可以调用派生类的相应函数。
(2)将show函数声明为虚函数,通过基类的指针来调用派生类的show函数。
(3)将计算两个日期相差天数的distance函数改为“—”运算符重载函数,使得计算两个日期相差天数更直观,增加程序的可读性。
提示:
储蓄账户一年算一次利息,而信用账户一月算一次利息。而使用基类指针来调用settle函数时,事先并不知道该指针所指向对象的具体类型,无法决定采用何种方式调用settle函数,因此只能将二者允许接收的参数统一为每月1日。同时对储蓄账户的settle函数进行修改,使它在结算利息之前先判断是否为1月,只有参数所给的日期是1月时才进行结算。
Main.cpp:
#include<iostream>
#include "account.h"
using namespace std;
Account::Account(int Id,double Balance)
{
id=Id;
balance=Balance;
}
void Account::show()
{
cout<<"\t账号:"<<getId()<<"\t\t余额:"<<getBalance()<<"元"<<endl;
}
void Account::getTotal()
{
cout<<"\t所有账户总金额:"<<total<<"元"<<endl;
}
SavingsAccount::SavingsAccount(int year,int month,int day,int id,double balance,double Rate):Account(id,balance),lastDate(year,month,day)
{
rate=Rate;
cout<<year<<"年"<<month<<"月"<<day<<"日";
cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
const double SavingsAccount::accumulate(Date date)
{
return (lastDate-date)*balance;
}
void SavingsAccount::deposit(Date date,double amount)
{
accumulation+=accumulate(date);
balance+=amount;
lastDate = date;
total+=amount;
cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
cout<<"\t账户"<<id<<"存入:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::withdraw(Date date,double amount)
{
accumulation+=accumulate(date);
balance-=amount;
lastDate = date;
total-=amount;
cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
cout<<"\t账户"<<id<<"取出:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::settle(Date date)
{
double settle = 0;
if(date.getYear()>lastDate.getYear())
{
for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
{
accumulation+=accumulate(date);
settle = accumulation/356*rate;
}
}
cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
cout<<"\t账户"<<id<<"结算利息:"<<settle<<"元"<<endl;
deposit(date,settle);
}
void SavingsAccount::show()
{
Account::show();
}
CreditAccount::CreditAccount(int year,int month,int day,int id,double balance,double Credit,double Rate,double Fee): Account(id,balance),lastDate(year,month,day)
{
credit=Credit;
fee=Fee;
rate=Rate;
cout<<year<<"年"<<month<<"月"<<day<<"日";
cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
double CreditAccount::getDebt(Date date)
{
settle(date);
return balance;
}
void CreditAccount::deposit(Date date,double amount)
{
settle(date);
if(credit<=0 || amount>credit)
{
date.show();
cout<<"\t账户"<<id<<"\t信用卡可用额度不足!"<<endl;
}
else
{
balance-=amount;
credit-=amount;
date.show();
cout<<"\t账户"<<id<<"\t信用卡已用额度:"<<amount<<"元"<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
total-=amount;
}
}
void CreditAccount::withdraw(Date date,double amount)
{
settle(date);
balance+=amount;
if((credit+amount)<=10000)
{
credit=credit+amount;
}
else
{
credit=10000;
}
total+=amount;
date.show();
cout<<"\t账户"<<id<<"\t信用卡还款:"<<amount<<"元 "<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
}
void CreditAccount::settle(Date date)
{
double settle=0;
if((date.getMonth()<lastDate.getMonth())||(date.getYear()>lastDate.getYear()))
{
for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
{
settle+=fee;
}
}
if(date.getDay()==1||date.getMonth()>lastDate.getMonth()||date.getYear()>lastDate.getYear())
{
if(date.getYear()==lastDate.getYear())
{
for(int j=1;j<=(date.getMonth()-lastDate.getMonth());j++)
{
for(int m=1;m<=lastDate-date;m++)
{
settle-=balance*rate;
}
}
}
else
{
for(int j=1;j<=(date.getMonth()-lastDate.getMonth())+12;j++)
{
for(int m=1;m<=lastDate-date;m++)
{
settle-=balance*rate;
}
}
}
}
else
{
settle-=0;
}
balance-=settle;
lastDate=date;
total-=settle;
}
void CreditAccount::show()
{
Account::show();
}
Account.h:
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include"date.h"
class Account
{
protected:
int id;
double balance;
static double total;
public:
Account(int id, double balance);
const int getId() {return id;}
const double getBalance() {return balance;}
static void getTotal();
virtual void deposit(Date date,double amount)=0;
virtual void withdraw(Date date,double amount)=0;
virtual void settle(Date date)=0;
virtual void show();
};
class SavingsAccount:public Account
{
protected:
double rate;
Date lastDate;
double accumulation=0;
const double accumulate(Date date);
public:
SavingsAccount(int year,int month,int day,int id,double balance,double rate);
void deposit(Date date,double amount);
void withdraw(Date date,double amount);
void settle(Date date);
const double getRate() {return rate;}
void show();
};
class CreditAccount:public Account
{
protected:
double credit;
double rate;
double fee;
Date lastDate;
public:
CreditAccount(int year,int month,int day,int id,double balance,double credit,double rate,double fee);
double getAvailableCredit() {return credit;}
void deposit(Date date,double amount);
void withdraw(Date date,double amount);
double getDebt(Date date);
void settle(Date date);
void show();
};
#endif // ACCOUNT_H_INCLUDED
Account.cpp:
#include<iostream>
#include "account.h"
using namespace std;
Account::Account(int Id,double Balance)
{
id=Id;
balance=Balance;
}
void Account::show()
{
cout<<"\t账号:"<<getId()<<"\t\t余额:"<<getBalance()<<"元"<<endl;
}
void Account::getTotal()
{
cout<<"\t所有账户总金额:"<<total<<"元"<<endl;
}
SavingsAccount::SavingsAccount(int year,int month,int day,int id,double balance,double Rate):Account(id,balance),lastDate(year,month,day)
{
rate=Rate;
cout<<year<<"年"<<month<<"月"<<day<<"日";
cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
const double SavingsAccount::accumulate(Date date)
{
return (lastDate-date)*balance;
}
void SavingsAccount::deposit(Date date,double amount)
{
accumulation+=accumulate(date);
balance+=amount;
lastDate = date;
total+=amount;
cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
cout<<"\t账户"<<id<<"存入:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::withdraw(Date date,double amount)
{
accumulation+=accumulate(date);
balance-=amount;
lastDate = date;
total-=amount;
cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
cout<<"\t账户"<<id<<"取出:"<<amount<<"元"<<"\t\t账户"<<id<<"余额:"<<balance<<"元"<<endl;
}
void SavingsAccount::settle(Date date)
{
double settle = 0;
if(date.getYear()>lastDate.getYear())
{
for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
{
accumulation+=accumulate(date);
settle = accumulation/356*rate;
}
}
cout<<date.getYear()<<"年"<<date.getMonth()<<"月"<<date.getDay()<<"日";
cout<<"\t账户"<<id<<"结算利息:"<<settle<<"元"<<endl;
deposit(date,settle);
}
void SavingsAccount::show()
{
Account::show();
}
CreditAccount::CreditAccount(int year,int month,int day,int id,double balance,double Credit,double Rate,double Fee): Account(id,balance),lastDate(year,month,day)
{
credit=Credit;
fee=Fee;
rate=Rate;
cout<<year<<"年"<<month<<"月"<<day<<"日";
cout<<"\tID为"<<id<<"的账户已创建成功!"<<endl;
}
double CreditAccount::getDebt(Date date)
{
settle(date);
return balance;
}
void CreditAccount::deposit(Date date,double amount)
{
settle(date);
if(credit<=0 || amount>credit)
{
date.show();
cout<<"\t账户"<<id<<"\t信用卡可用额度不足!"<<endl;
}
else
{
balance-=amount;
credit-=amount;
date.show();
cout<<"\t账户"<<id<<"\t信用卡已用额度:"<<amount<<"元"<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
total-=amount;
}
}
void CreditAccount::withdraw(Date date,double amount)
{
settle(date);
balance+=amount;
if((credit+amount)<=10000)
{
credit=credit+amount;
}
else
{
credit=10000;
}
total+=amount;
date.show();
cout<<"\t账户"<<id<<"\t信用卡还款:"<<amount<<"元 "<<"\t信用卡剩余额度:"<<credit<<"元"<<endl;
}
void CreditAccount::settle(Date date)
{
double settle=0;
if((date.getMonth()<lastDate.getMonth())||(date.getYear()>lastDate.getYear()))
{
for(int i=1;i<=date.getYear()-lastDate.getYear();i++)
{
settle+=fee;
}
}
if(date.getDay()==1||date.getMonth()>lastDate.getMonth()||date.getYear()>lastDate.getYear())
{
if(date.getYear()==lastDate.getYear())
{
for(int j=1;j<=(date.getMonth()-lastDate.getMonth());j++)
{
for(int m=1;m<=lastDate-date;m++)
{
settle-=balance*rate;
}
}
}
else
{
for(int j=1;j<=(date.getMonth()-lastDate.getMonth())+12;j++)
{
for(int m=1;m<=lastDate-date;m++)
{
settle-=balance*rate;
}
}
}
}
else
{
settle-=0;
}
balance-=settle;
lastDate=date;
total-=settle;
}
void CreditAccount::show()
{
Account::show();
}
Date.h:
#ifndef DATE_H_INCLUDED
#define DATE_H_INCLUDED
class Date
{
int year, month, 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; }
void show() const;
bool isLeapYear(int year) const;
int operator-(const Date &date) const {return date.totalDays-totalDays;}
};
#endif // DATE_H_INCLUDED
Date.cpp:
#include<iostream>
#include "date.h"
using namespace std;
Date::Date(int Year, int Month, int Day)
{
year=Year;
month=Month;
day=Day;
int Days=0;
for(int i=0;i<year;i++)
{
if(isLeapYear(i)==true)
Days=Days+366;
else
Days=Days+365;
}
switch(month){
case 1:Days+=0;break;
case 2:Days+=31;break;
case 3:Days+=59;break;
case 4:Days+=90;break;
case 5:Days+=120;break;
case 6:Days+=151;break;
case 7:Days+=181;break;
case 8:Days+=212;break;
case 9:Days+=243;break;
case 10:Days+=273;break;
case 11:Days+=304;break;
case 12:Days+=334;break;
default:cout<<"month error!"<<endl;
}
totalDays=Days+day;
}
void Date::show() const
{
cout<<getYear()<<"年"<<getMonth()<<"月"<<getDay()<<"日";
}
bool Date::isLeapYear(int year) const
{
if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
return true;
else
return false;
}
运行截图:
学习掌握
动态联编,即是系统在运行时动态实现某个动作。而动态联编就是通过虚函数来实现的,因此学习了虚函数的定义以及使用方法及注意点,比如就要确保虚函数再定义时,参数表要与原先的保持完全一致。
具有虚函数的类就是抽象类,如果在抽象类的派生类中没有重新说明纯虚函数,则该函数在派生类中仍然为纯虚函数,而这个派生类仍然还是一个抽象类。