抽象ベースクラス(ABC)、純虚関数

23796 ワード

#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; }