抽象基类(ABC),纯虚函数

#ifndef _ACCTABC_H_
#define _ACCTABC_H_
//(*
#include <iostream>
#include <string>
//*)
//Abstract Base Class
class AcctABC
{
private:
    std::string fullName;
    long acctNum;
    double balance;

protected:
    struct Formatting
    {
        std::ios_base::fmtflags flag;
        std::streamsize pr;
    };
    const std::string & FullName(void) const {return fullName;}
    long AcctNum(void) const {return acctNum;}
    Formatting SetFormat(void) const;
    void Restore(Formatting & f) const;

public:
    AcctABC(const std::string & s = "Nullbody", long an = -1, double bal = 0.0);
    void Deposit(double amt);
    virtual void Withdraw(double amt) = 0;  //pure virtual function
    double Balance(void) const {return balance;};
    virtual void ViewAcct(void) const = 0;  //pure virtual function
    virtual ~AcctABC() {}
};

//Brass Account Class
class Brass : public AcctABC
{
public:
    Brass(const std::string & s = "Nullbody", long an = -1, double bal = 0.0) : AcctABC(s, an, bal) {}
    virtual void Withdraw(double amt);
    virtual void ViewAcct(void) const;
    virtual ~Brass() {}
};

//Brass Plus Account Class
class BrassPlus : public AcctABC
{
private:
    double maxLoan;
    double rate;
    double owesBank;

public:
    BrassPlus(const std::string & s = "Nullbodt", long an = -1, double bal = 0.0, double ml = 500, double r = 0.10);
    BrassPlus(const Brass & ba, double ml = 500, double r = 0.1);
    virtual void ViewAcct(void) const;
    virtual void Withdraw(double amt);
    void ResetMax(double m) {maxLoan = m;}
    void ResetRate(double r) {rate = r;}
    void ResetOwes(void) {owesBank = 0;}
};

#endif
#include <iostream>
#include "acctabc.h"
using std::cout;
using std::ios_base;
using std::endl;
using std::string;

//Abstract Base class
AcctABC::AcctABC(const string & s, long an, double bal)
{
    fullName = s;
    acctNum = an;
    balance = bal;
}

void AcctABC::Deposit(double amt)
{
    if(amt < 0)
    {
        cout << "Negative deposit not allowed; deposit is cancelled." << endl;
    }
    else
    {
        balance += amt;
    }
}

void AcctABC::Withdraw(double amt)
{
    balance -= amt;
}

//protected methods for formatting
AcctABC::Formatting AcctABC::SetFormat(void) const
{
    //set up ###.## format
    Formatting f;
    f.flag = cout.setf(ios_base::fixed, ios_base::floatfield);
    f.pr = cout.precision(2);
    return f;
}

void AcctABC::Restore(Formatting & f) const
{
    cout.setf(f.flag, ios_base::floatfield);
    cout.precision(f.pr);
}

//Brass methods
void Brass::Withdraw(double amt)
{
    if(amt < 0)
    {
        cout << "Withdrawal amount must be positive; withdrawal canceled." << endl;
    }
    else if(amt < Balance())
    {
        AcctABC::Withdraw(amt);
    }
    else
    {
        cout << "Withdrawal amount of $" << amt << " exceeds your balance." << endl << "Withdrawal canceled." << endl;
    }
}

void Brass::ViewAcct(void) const
{
    Formatting f = SetFormat();
    cout << "Brass Client: " << FullName() << endl;
    cout << "Account Number: " << AcctNum() << endl;
    cout << "Balance: $" << Balance() << endl;
    Restore(f);
}

//BrassPlus Methods
BrassPlus::BrassPlus(const string & s, long an, double bal, double ml, double r) : AcctABC(s, an, bal)
{
    maxLoan = ml;
    owesBank = 0.0;
    rate = r;
}

BrassPlus::BrassPlus(const Brass & ba, double ml, double r) : AcctABC(ba)
{
    maxLoan = ml;
    owesBank = 0.0;
    rate = r;
}

void BrassPlus::ViewAcct(void) const
{
    Formatting f = SetFormat();

    cout << "BrassPlus Client: " << FullName() << endl;
    cout << "Account Number: " << AcctNum() << endl;
    cout << "Balance: $" << Balance() << endl;
    cout << "Maxinum loan: $" << maxLoan <<endl;
    cout << "Owed to bank: $" << owesBank << endl;
    cout.precision(3);
    cout << "Loan Rate: " << 100 * rate << "%
";
    Restore(f);
}

void BrassPlus::Withdraw(double amt)
{
    Formatting f = SetFormat();

    double bal = Balance();
    if(amt <= bal)
    {
        AcctABC::Withdraw(amt);
    }
    else if(amt <= bal + maxLoan - owesBank)
    {
        double advance = amt - bal;
        owesBank += advance * (1.0 + rate);
        cout << "Bank advance: $" << advance * rate << endl;
        Deposit(advance);
        AcctABC::Withdraw(amt);
    }
    else
    {
        cout << "Credit limit exceeded. Transaction cancelled." << endl;
    }
    Restore(f);
}
#include <iostream>
#include <string>
#include "acctabc.h"
const int CLIENTS = 4;

int main(void)
{
    using std::cin;
    using std::cout;
    using std::endl;

    AcctABC * 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
        {
            double tmax, trate;
            cout << "Enter the overdraft limit: $";
            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() != '
')
        {
            continue;
        }
    }
    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.
";

    return 0;
}
原文地址:https://www.cnblogs.com/pingge/p/3363832.html