#include "bank.h"
#include "checkingaccount.h"
#include "i_account.h"
#include "savingsaccount.h"
int main()
{
Bank bank;
CheckingAccount::SetInterestRate(0.001);
SavingsAccount::SetInterestRate(0.0075);
for (auto i = 0; i < 50; i++) {
auto account = bank.OpenCheckingAccount();
account->Deposit(i * 100.0);
}
for (auto i = 0; i < 50; i++) {
auto account = bank.OpenSavingsAccount();
account->Deposit(i * 100.0);
}
for (auto i = 0; i < 20; i++) {
auto account = bank.OpenPocketMoneyAccount();
account->Deposit(5.0);
}
bank.PayInterest();
return 0;
}
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include "i_account.h"
class Account : public IAccount {
private:
double balance_{};
public:
double GetBalance() const noexcept;
void Deposit(double amount) noexcept final;
double CalculateInterest() noexcept override;
void SetOverdraft(double amount) noexcept override;
protected:
void SetBalance(double balance) noexcept;
};
#endif // ACCOUNT_H_
#ifndef BANK_H_
#define BANK_H_
#include <list>
#include <memory>
class IAccount;
class Bank {
private:
std::list<std::shared_ptr<IAccount>> accounts_;
public:
std::shared_ptr<IAccount> OpenSavingsAccount();
std::shared_ptr<IAccount> OpenCheckingAccount();
std::shared_ptr<IAccount> OpenPocketMoneyAccount();
void PayInterest();
private:
std::shared_ptr<IAccount> OpenAccount(std::shared_ptr<IAccount> new_account);
};
#endif // BANK_H_
#ifndef CHECKINGACCOUNT_H_
#define CHECKINGACCOUNT_H_
#include "account.h"
class CheckingAccount : public Account {
private:
static double interest_rate_;
double overdraft_{};
public:
static double GetInterestRate() noexcept;
static void SetInterestRate(double interest_rate) noexcept;
double Withdraw(double amount) noexcept override;
double CalculateInterest() noexcept override;
void SetOverdraft(double amount) noexcept override;
};
#endif // CHECKINGACCOUNT_H_
#ifndef I_ACCOUNT_H_
#define I_ACCOUNT_H_
class IAccount {
public:
virtual ~IAccount() = default;
virtual void Deposit(double amount) = 0;
virtual double Withdraw(double amount) = 0;
virtual double CalculateInterest() = 0;
virtual void SetOverdraft(double amount) = 0;
};
#endif // I_ACCOUNT_H_
#ifndef POCKET_MONEY_ACCOUNT_H_
#define POCKET_MONEY_ACCOUNT_H_
#include "account.h"
class PocketMoneyAccount : public Account {
public:
double Withdraw(double amount) noexcept override;
};
#endif // POCKET_MONEY_ACCOUNT_H_
#ifndef SAVINGSACCOUNT_H_
#define SAVINGSACCOUNT_H_
#include "account.h"
class SavingsAccount : public Account {
private:
static double interest_rate_;
public:
static double GetInterestRate() noexcept;
static void SetInterestRate(double interest_rate) noexcept;
double Withdraw(double amount) noexcept override;
double CalculateInterest() noexcept override;
};
#endif // SAVINGSACCOUNT_H_
#include "account.h"
double Account::GetBalance() const noexcept { return balance_; }
void Account::Deposit(const double amount) noexcept { balance_ += amount; }
double Account::CalculateInterest() noexcept { return 0.0; }
void Account::SetOverdraft(double amount) noexcept {}
void Account::SetBalance(double balance) noexcept { balance_ = balance; }
#include "bank.h"
#include "checkingaccount.h"
#include "i_account.h"
#include "pocket_money_account.h"
#include "savingsaccount.h"
std::shared_ptr<IAccount> Bank::OpenSavingsAccount()
{
const auto account = std::make_shared<SavingsAccount>();
return OpenAccount(account);
}
std::shared_ptr<IAccount> Bank::OpenCheckingAccount()
{
const auto account = std::make_shared<CheckingAccount>();
return OpenAccount(account);
}
std::shared_ptr<IAccount> Bank::OpenPocketMoneyAccount()
{
const auto account = std::make_shared<PocketMoneyAccount>();
return OpenAccount(account);
}
std::shared_ptr<IAccount> Bank::OpenAccount(
std::shared_ptr<IAccount> new_account)
{
accounts_.push_back(new_account);
return new_account;
}
void Bank::PayInterest()
{
for (auto& account : accounts_) {
const auto interest = account->CalculateInterest();
account->Deposit(interest);
}
}
#include "checkingaccount.h"
double CheckingAccount::interest_rate_{};
double CheckingAccount::GetInterestRate() noexcept { return interest_rate_; }
void CheckingAccount::SetInterestRate(const double interest_rate) noexcept
{
interest_rate_ = interest_rate;
}
double CheckingAccount::Withdraw(const double amount) noexcept
{
double withdrawn;
auto balance = GetBalance();
if (balance + overdraft_ > amount) {
withdrawn = amount;
}
else if (balance + overdraft_ > 0.0) {
withdrawn = balance + overdraft_;
}
else {
withdrawn = 0.0;
}
balance -= withdrawn;
SetBalance(balance);
return withdrawn;
}
double CheckingAccount::CalculateInterest() noexcept
{
const auto interest = GetBalance() * GetInterestRate();
return interest;
}
void CheckingAccount::SetOverdraft(const double amount) noexcept
{
overdraft_ = amount;
}
#include "pocket_money_account.h"
double PocketMoneyAccount::Withdraw(const double amount) noexcept
{
auto withdrawn = amount;
auto balance = GetBalance();
if (balance < amount) {
withdrawn = balance;
}
balance -= withdrawn;
SetBalance(balance);
return withdrawn;
}
#include "savingsaccount.h"
double SavingsAccount::interest_rate_{};
double SavingsAccount::GetInterestRate() noexcept { return interest_rate_; }
void SavingsAccount::SetInterestRate(const double interest_rate) noexcept
{
interest_rate_ = interest_rate;
}
double SavingsAccount::Withdraw(const double amount) noexcept
{
auto balance = GetBalance();
balance -= amount;
SetBalance(balance);
return amount;
}
double SavingsAccount::CalculateInterest() noexcept
{
const auto interest = GetBalance() * GetInterestRate();
return interest;
}