#include <cstdlib>

class BankAccount1 {
public:
	BankAccount1(double balance) : balance(balance) {}
	~BankAccount1() {}
	
	const double &getBalance() const { return balance; }
	const double &deposit(double amt) { return (balance += amt); }
	const double &withdraw(double amt) {
		if (amt > balance) {
			exit(EXIT_FAILURE);
		}
		else {
			return (balance -= amt);
		}
	}
private:
	double balance;
};

/* first example of derived class, but won't compile since
I'm accessing private member in accrueInterest */
class SavingsAccount1Bad : public BankAccount1 {
public:
	/* rate must be set in an initializer since it is a const */
	SavingsAccount1Bad(double balance, double rate) :
		BankAccount1(balance), rate(rate) {}
	~SavingsAccount1Bad() {}
	
	/*const double& accrueInterest() { return (balance *= (1.0+rate)); } */

private:
	const double rate;
};

/* second example -- use public member functions to get at 
private members */
class SavingsAccount1Good : public BankAccount1 {
public:
	/* rate must be set in an initializer since it is a const */
	SavingsAccount1Good(double balance, double rate) :
		BankAccount1(balance), rate(rate) {}
	~SavingsAccount1Good() {}
	
	const double& accrueInterest() { 
		double interest = rate * getBalance();
		return deposit(interest);
	}

private:
	const double rate;
};

/* balance is protected rather than private -- allows derived classes to
access it */
class BankAccount2 {
public:
	BankAccount2(double balance) : balance(balance) {}
	~BankAccount2() {}
	
	const double &getBalance() const { return balance; }
	const double &deposit(double amt) { return (balance += amt); }
	const double &withdraw(double amt) {
		if (amt > balance) {
			exit(EXIT_FAILURE);
		}
		else {
			return (balance -= amt);
		}
	}
protected:
	double balance;
};

/* derived class access protected member of base class */
class SavingsAccount2 : public BankAccount2 {
public:
	/* rate must be set in an initializer since it is a const */
	SavingsAccount2(double balance, double rate) :
		BankAccount2(balance), rate(rate) {}
	~SavingsAccount2() {}
	
	const double& accrueInterest() { 
		return (balance *= (1.0+rate)); 
	}

private:
	const double rate;
};

