P499 usebrass2
有两种方式可以实现多态公有继承
- 在派生类中重新定义基类的方法
- 使用虚方法
 如下是使用虚方法
 brass.h
#ifndef BRASS_H
#define BRASS_H
#include <string>
class Brass{
private:
    std::string fullName;  //客户姓名
    long acctNum;  //账号
    double balance;  //当前结余
public:
    Brass(const std::string & s="Nullbody",long an=-1,
          double bal=0.0);
    void Deposit(double amt);  //存款
    virtual void withdraw(double amt);  //取款
    double Balance() const; //显示余额
    virtual void ViewAcct() const;
    virtual ~Brass() {}
};
//Brass Plus Account Class
class BrassPlus:public Brass
{
private:
    double maxLoan;  //透支的上线
    double rate;  //透支贷款利率
    double owesBank;  //当前的透支额度
public:
    BrassPlus(const std::string &s="Nullbody",long an=-1,
              double bal=0.0,double ml=500,double r=0.11125);
    BrassPlus(const Brass &ba,double ml=500,
                              double r=0.11125);
    virtual void ViewAcct() const;
    virtual void withdraw(double amt);
    void ResetMax(double m){maxLoan=m;};
    void ResetRate(double r){rate=r;};
    void ResetOwes() {owesBank=0;};
};
#endif // BRASS_H
main.cpp
#include <iostream>
#include "brass.h"
using namespace std;
//formatting stuff
typedef std::ios_base::fmtflags format;
typedef std::streamsize precis;
format setFormat();
void restore(format f,precis p);
//Brass methods
Brass::Brass(const string &s, long an, double bal)
{
    fullName=s;
    acctNum=an;
    balance=bal;
}
//储蓄函数
void Brass::Deposit(double amt)
{
    if(amt<0)
    {
        cout<<"Negative deposit not allowed;"
           <<"deposit is cancelled\n";
    }
    else
        balance=balance+amt;
}
void Brass::withdraw(double amt)
{
    //set up ###.##format
    format initialState=setFormat();
    precis prec=cout.precision(2);
    if(amt<0)
    {
        cout<<"withdrawal amouut must be positive;"
           <<"withdrawal canceled\n";
    }
    else if(amt<=balance)
    {
        balance=balance-amt;
    }
    else
    {
        cout<<"withrdrawl amout of $"<<amt
           <<" exceeds your balance\n"
          <<"withdrawal canceled\n";
    }
    restore(initialState,prec);
}
double Brass::Balance() const
{
    return balance;
}
void Brass::ViewAcct() const
{
    //set up ###.## format
    format initialState=setFormat();
    precis prec=cout.precision(2);
    cout<<"Client:"<<fullName<<endl;
    cout<<"Account Number:"<<acctNum<<endl;
    cout<<"Balance:$"<<balance<<endl;
    restore(initialState,prec);  //存储原始的格式
}
//BrassPlus的方法
BrassPlus::BrassPlus(const string &s,
                     long an, double bal,
                     double ml, double r):Brass(s,an,bal)
{
    //构造函数
    maxLoan=ml;
    owesBank=0.0;
    rate=r;
}
BrassPlus::BrassPlus(const Brass &ba, double ml, double r):Brass(ba)
{
    maxLoan=ml;
    owesBank=0.0;
    rate=r;
}
//重定义
void BrassPlus::ViewAcct() const
{
    //set up ###.##format
    format initialState=setFormat();
    precis prec=cout.precision(2);
    Brass::ViewAcct();  //显示基类的部分
    cout<<"Maximum loan:$"<<maxLoan<<endl;
    cout<<"Owed to back:$"<<owesBank<<endl;
    cout.precision(3);
    cout<<"Loan Rate"<<100*rate<<"%\n";
    restore(initialState,prec);
}
//重定义
//如果用户提取的金额超过了结余,该方法将安排贷款
void BrassPlus::withdraw(double amt)
{
    format initialState=setFormat();
    precis prec=cout.precision(2);
    //使用Balance()函数来确定结余
    double bal=Balance();
    if(amt<=bal)
    {
        //提款少于存款,提款成功
        Brass::withdraw(amt);  //继承类中调用基类的方法
    }
    else if(amt<=bal+maxLoan-owesBank)
    {
        double advance=amt-bal;
        owesBank+=advance*(1.0+rate);  //owesBank当前的透支额度
        cout<<"Bank advance:$"<<advance<<endl;
        cout<<"Finance charge:$"<<advance*rate<<endl;
        Deposit(advance);  //放贷
        //放贷成功后可以今天提款
        Brass::withdraw(amt);
    }
    else
    {
        cout<<"Credit limit exceeded.Transaction cancelled.\n";
    }
    restore(initialState,prec);
}
format setFormat()
{
    //set up ###.## format
    return cout.setf(std::ios_base::fixed,
                     std::ios_base::floatfield);
}
void restore(format f, precis p)
{
    cout.setf(f,std::ios_base::floatfield);
    cout.precision(p);
}
const int CLIENTS=4;
int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    Brass * p_clients[CLIENTS];
    std::string temp;
    long tempnum;
    double tempbal;
    char kind;
    for(int i=0;i<CLIENTS;i++)
    {
        cout<<"Enter client's name:";  //输入账户姓名
        getline(cin,temp);
        cout<<"Enter client's account number:";
        cin>>tempnum;
        cout<<"Enter opening balance:$";
        cin>>tempbal;
        cout<<"Enter 1 for Brass Account or"
           <<"2 for BrassPlus Account:";
        while(cin>>kind &&(kind!='1' && kind!='2'))
            cout<<"Enter either 1 or 2";
        if(kind == '1')
        {
            p_clients[i]=new Brass(temp,tempnum,tempbal);
        }
        else  //输入的kind是2
        {
            double tmax,trate;
            cout<<"Enter the overdraft limit:$";  //overdraft 透支
            cin>>tmax;
            cout<<"Enter the interest rate"
               <<"as a decimal fraction:";
            cin>>trate;
            p_clients[i]=new BrassPlus(temp,tempnum,tempbal,tmax,trate);
        }
        while(cin.get()!='\n')
            continue;
    }  //for(int i=0;i<CLIENTS;i++)
    cout<<endl;
    for(int i=0;i<CLIENTS;i++)
    {
        p_clients[i]->ViewAcct();
        cout<<endl;
    }
    for(int i=0;i<CLIENTS;i++)
    {
        delete p_clients[i];  //释放内存
    }
    cout<<"Done.\n";
    return 0;
}
运行效果如下

开发环境Qt Creator 4.0.3 (Community)
P499 usebrass2的更多相关文章
- C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域
		面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ... 
- Linux:用at和crontab调度作业
		一.有2种作业调度方式 1.突发性的,就是只运行作业一次而不是定期运行,使用at命令. 例如在进程A运行一段时间后关闭该进程. 2.定期运行,就是每隔一定的周期运行一次,使用crontab命令. 如每 ... 
- entity framework core 支持批量插入,值得期待
		entity framework6.x之前搞了这么多版本,构架这么牛B,居然没有批量插入更新的功能,但有很多替换的解决方案,例如Entity Framework Extended Library(ht ... 
- 用kotlin方式打开《第一行代码:Android》之开发酷欧天气(1)
		参考:<第一行代码:Android>第2版--郭霖 注1:本文为原创,例子可参考郭前辈著作:<第一行代码:Android>第2版 注2:本文不赘述android开发的基本理论, ... 
- 安卓巴士android源码、博文精选1
		每周精选 第 53 期 精品源码 Android开源项目--CookMan 厨客APP 简介CookMan,厨客,是一款查询.搜索.分类.收藏菜谱功能的APP.|52数据来源Mob A ... 
- 《Java大学教程》—第20章 文件处理
		记录():一个单独的数据实例.域():一个属性. 20.3 输入和输出设备:P484输入过程和输出过程.操作系统负责建立三个流(stream):标准输入流(System.in).标准输出流(Sy ... 
- C++学习笔记----4.4 继承情况下的类作用域嵌套
		引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:如果不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这种类作用域的层次嵌套使我们能够直接访问基类的成员,就好像这些成员 ... 
随机推荐
- 做了 3 年企业级 SaaS,我收获的 10 点心得(转)
			关于中国企业级服务的总结不少,本土派和海外派都有出色的文章出来,VC 和创业者站在各自角度也有很多不错的总结.本文基于 Ping++ 近三年的创业历程而来,有弯路,有教训,有醒悟,也有心得.盛景 B2 ... 
- Machine Learning - Andrew Ng - Coursera
			Machine Learning - Andrew Ng - Coursera Contents 1 Notes 1 Notes What is Machine Learning? Two defin ... 
- mysql读写分离[高可用]
			顾名思义, 在mysql负载均衡中有多种方式, 本人愚钝,只了解驱动中间件和mysql_proxy两种方式, 对于驱动,利用的是ReplicationDriver,具体请看远哥的这篇文章: MySQL ... 
- 2018-2019-1 20189206  vim.c插件安装
			vim插件安装 vim插件安装 由于今天在安装vim.c插件耗费了很多时间,配置文件一直不生效,特此记录以下安装插件的方法. 安装vim.c按照博客的方法 第一步:创建目录~/.vim 这个目录是用来 ... 
- repo回退当前分支下所有仓库到指定日期前的最新代码版本【转】
			本文转载自:https://blog.csdn.net/u011006622/article/details/70272087 执行下面这样的repo命令就行了: repo forall -c 'c ... 
- SQL 基础语法笔记教程整理
			最近从图书馆借了本介绍 SQL 的书,打算复习一下基本语法,记录一下笔记,整理一下思路,以备日后复习之用. PS:本文适用 SQL Server2008 语法. 首先,附一个发现的 MySQL 读书笔 ... 
- GC 垃圾收集
			算法: 没有使用引用计数算法.使用的是GC Roots 可达性算法. 复制算法:新生代,老年代. 标记-整理算法:一般会对对象标记几次才会清理掉.然后从新整理物理内存空间. 分代收集算法:更加对象存活 ... 
- [ajaxupload] - 上传文件同时附件参数值
			$.ajax({ url: '/excel/importExcel?instance='+"品种1", type: 'POST', data: formData, 上面前端通过?拼 ... 
- (转载)C#:Enum、Int和String的互相转换,枚举转换
			Enum为枚举提供基类,其基础类型可以是除 Char 外的任何整型.如果没有显式声明基础类型,则使用 Int32.编程语言通常提供语法来声明由一组已命名的常数和它们的值组成的枚举.注意:枚举类型的基类 ... 
- 【OData】Odata能做什么?
			在我看来OData就是一个实现Rest full的框架.你可以使用它对server的资源进行操作.那么它能做什么? 1. 获取资源 var context = new DefaultContainer ... 
