抽象基类(ABC)
被调用方法为虚拟,所以根据调方法的对象类型来判断,使用合适的成员函数
//////////////////////////////////////////////////////
///////////////////main.cpp///////////////////////////
// usebrass3.cpp -- polymorphic example, abstract base class
// compile with brass.cpp
#include <iostream>
#include "acctabc.h"
const int CLIENTS = 4;
const int LEN = 40;
int main()
{
using std::cin;
using std::cout;
using std::endl;
AcctABC * p_clients[CLIENTS];
int i;
for (i = 0; i < CLIENTS; i++)
{
char temp[LEN];
long tempnum;
double tempbal;
char kind;
cout << "Enter client's name: ";
cin.getline(temp, LEN);
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() != '\n')
continue;
}
cout << endl;
for (i = 0; i < CLIENTS; i++)
{
p_clients[i]->ViewAcct();
cout << endl;
}
for (i = 0; i < CLIENTS; i++)
{
delete p_clients[i]; // free memory
}
cout << "Done.\n";
return 0;
}
///////////////////////////////////////////////////
////////////////acctabc.h//////////////////////////
// acctabc.h -- bank account classes
#ifndef ACCTABC_H_
#define ACCTABC_H_
// Abstract Base Class
class AcctABC
{
private:
enum {MAX = 35};
char fullName[MAX];
long acctNum;
double balance;
protected: //共有继承的类可以直接调用保护成员,但不能直接调用私有成员
const char * FullName() const {return fullName;}
long AcctNum() const {return acctNum;}
std::ios_base::fmtflags SetFormat() const;
public:
AcctABC(const char *s = "Nullbody", long an = -1,
double bal = 0.0);
void Deposit(double amt) ;
virtual void Withdraw(double amt) = 0; // pure virtual function 纯虚拟函数可以不写在定义中
double Balance() const {return balance;};
virtual void ViewAcct() const = 0; // pure virtual function
virtual ~AcctABC() {}
};
// Brass Account Class
class Brass :public AcctABC
{
public:
Brass(const char *s = "Nullbody", long an = -1,
double bal = 0.0) : AcctABC(s, an, bal) { }
virtual void Withdraw(double amt);
virtual void ViewAcct() const;
virtual ~Brass() {}
};
//Brass Plus Account Class
class BrassPlus : public AcctABC
{
private:
double maxLoan;
double rate;
double owesBank;
public:
BrassPlus(const char *s = "Nullbody", 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()const;
virtual void Withdraw(double amt);
void ResetMax(double m) { maxLoan = m; }
void ResetRate(double r) { rate = r; };
void ResetOwes() { owesBank = 0; }
};
#endif
////////////////////////////////////////////////////////
///////////acctabc.cpp//////////////////////////////////
// acctabc.cpp -- bank account class methods
#include <iostream>
#include <cstring>
using std::cout;
using std::ios_base;
using std::endl;
#include "acctabc.h"
// Abstract Base Class
AcctABC::AcctABC(const char *s, long an, double bal)
{
strncpy(fullName, s, MAX - 1);
fullName[MAX - 1] = '\0';
acctNum = an;
balance = bal;
}
void AcctABC::Deposit(double amt)
{
if (amt < 0)
cout << "Negative deposit not allowed; "
<< "deposit is cancelled.\n";
else
balance += amt;
}
void AcctABC::Withdraw(double amt)
{
balance -= amt;
}
// protected method
ios_base::fmtflags AcctABC::SetFormat() const
{
// set up ###.## format
ios_base::fmtflags initialState =
cout.setf(ios_base::fixed, ios_base::floatfield);
cout.setf(ios_base::showpoint);
cout.precision(2);
return initialState;
}
// Brass methods
void Brass::Withdraw(double amt)
{
if (amt < 0)
cout << "Withdrawal amount must be positive; "
<< "withdrawal canceled.\n";
else if (amt <= Balance())
AcctABC::Withdraw(amt);
else
cout << "Withdrawal amount of $" << amt
<< " exceeds your balance.\n"
<< "Withdrawal canceled.\n";
}
void Brass::ViewAcct() const
{
ios_base::fmtflags initialState = SetFormat();
cout << "Brass Client: " << FullName() << endl;
cout << "Account Number: " << AcctNum() << endl;
cout << "Balance: $" << Balance() << endl;
cout.setf(initialState);
}
// BrassPlus Methods
BrassPlus::BrassPlus(const char *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) // uses implicit copy constructor
{
maxLoan = ml;
owesBank = 0.0;
rate = r;
}
void BrassPlus::ViewAcct() const
{
ios_base::fmtflags initialState = SetFormat();
cout << "BrassPlus Client: " << FullName() << endl;
cout << "Account Number: " << AcctNum() << endl;
cout << "Balance: $" << Balance() << endl;
cout << "Maximum loan: $" << maxLoan << endl;
cout << "Owed to bank: $" << owesBank << endl;
cout << "Loan Rate: " << 100 * rate << "%\n";
cout.setf(initialState);
}
void BrassPlus::Withdraw(double amt)
{
ios_base::fmtflags initialState = 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 << endl;
cout << "Finance charge: $" << advance * rate << endl;
Deposit(advance);
AcctABC::Withdraw(amt);
}
else
cout << "Credit limit exceeded. Transaction cancelled.\n";
cout.setf(initialState);
}


浙公网安备 33010602011771号