// TBD in this file
// (1) create a helper function `CreateBankAccounts` which
// in the variable `bank` (see below in `main` - handed over
// as first argunent of type `Bank*`) creates 10 accounts
// with an `InterestCalculator` handed over via reference by
// the second argument. A an amount of 2.0, 4.0, 6.0 ... etc.
// should be deposited to the 10 accounts.
// (2) replace the loop in `main` below in main with calling the
// helper function two times (so that 20 accounts are created)
// using an `InterestCalculator` paying 1% for the first 10
// accounts and paying 0.75% for the second 10 accounts
//
#include "account.h"
#include "bank.h"
#include "logger.h"
int main()
{
Logger::LogLine("Banking program: Start");
Bank bank;
for (auto i = 0; i < 10; i++) {
auto account = bank.CreateAccount();
account->Deposit(i * 2.0);
account->SetType(AccountType::kCheckingAccount);
}
bank.PayInterest();
Logger::LogLine("\nBanking program: End");
return 0;
}
// TBD in this file:
// (1) complete the below to define an interface with the
// member function (pure virtual)
// `double CalculateInterest(double) const`
class IInterestCalculator {
virtual ~IInterestCalculator() =default;
};
// TBD in this file:
// (1) include the file "i_interest_calculator.h"
// (2) define the class `InterestCalculator` to implement the
// interface `IInterestCalculator` with
// - a private data member `double interest_rate_` set to
// zero with direct member initialization
// - a public constructor with an argument of type `double`
// to set the data member `interest_rate_` to a different
// value
// - a public getter for the data member
// - the prototype of the member function
// double CalculateInterest(double balance) const override
// Note: the IMPLEMENTATION of this member function shall be
// done in file `interest_calculator.cpp`
//
#ifndef INTEREST_CALCULATOR_H_
#define INTEREST_CALCULATOR_H_
#include "i_interest_calculator.h"
class InterestCalculator : public IInterestCalculator {
private:
double interest_rate_{};
public:
explicit InterestCalculator(double interest_rate);
double GetInterestRate() const;
double CalculateInterest(double balance) const override;
};
#endif // INTEREST_CALCULATOR_H_
// TBD in this file
// (1) include the header file `interest_calculator.h`
// (2) implement the member function `CalculateInterest` of
// class `InterestCalculator` to calculate and return the
// interest AMOUNT for a balance received as argument and
// the rate as of the data member `interest_rate_`
#include "i_interest_calculator.h"
// TBD in this file
// (1) remove this header file (`account_type.h`)
//
#ifndef ACCOUNT_TYPE_H_
#define ACCOUNT_TYPE_H_
enum class AccountType {
kInvalid,
kCheckingAccount,
kSavingsAccount,
};
#endif // ACCOUNT_TYPE_H_
// TBD in this file
// (1) replace the include of file "account_type.h" with an
// include of file "i_interest_calculator.h"
// (2) replace the data member `AccounType type_` with an
// `IInterrestCalculator& interest_calculator_`
// (3) To the constructor `Account` add an argument of type
// `const IInterestCalculator&`
// (4) remove the prototypes of the getter and setter for the
// `AccountType`
#ifndef ACCOUNT_H_
#define ACCOUNT_H_
#include "account_type.h"
class Account {
private:
double balance_;
AccountType type_;
public:
Account() noexcept;
double GetBalance() const noexcept;
AccountType GetType() const noexcept;
void SetType(AccountType type) noexcept;
void Deposit(double amount);
double Withdraw(double amount);
double CalculateInterest() const;
};
#endif // ACCOUNT_H_
// TBD in this file:
// (1) Modify the constructor of class `Account` to take an argument
// of type `I_InterestCalculator&` instead of `AccountType`
// (2) remove the getter and the setter for the `AccountType`
// (3) in `Account::CalculateInterest` remove the switch-statement
// statement calculating the the `AccountType`-specific interest
// leaving the result in the local variable `interest_rate`
// (4) also in `Account::CalculateInterest` replace calculating
// interest amount as
// interest = balance_ * interest_rate;
// with
// interest = balance * interest_calculator.CalculateInterest(balance_);
//
#include "account.h"
#include "logger.h"
Account::Account() noexcept : balance_{0.0}, type_{AccountType::kInvalid} {}
double Account::GetBalance() const noexcept { return balance_; }
AccountType Account::GetType() const noexcept { return type_; }
void Account::SetType(const AccountType type) noexcept { type_ = type; }
void Account::Deposit(const double amount)
{
balance_ += amount;
Logger::Log("\nDeposit, balance: ");
Logger::LogLine(balance_);
}
double Account::Withdraw(const double amount)
{
balance_ -= amount;
Logger::Log("\nWithdraw, balance: ");
Logger::LogLine(balance_);
return amount;
}
double Account::CalculateInterest() const
{
auto interest_rate = 0.0;
switch (type_) {
case AccountType::kCheckingAccount: {
interest_rate = 0.001;
break;
default:
break;
}
}
const auto interest = balance_ * interest_rate;
Logger::Log("\nCalculate interest, amount: ");
Logger::LogLine(interest);
return interest;
}
// TBD in this file:
// (1) include the header file "i_interest_calculator"
// (2) modify the prototype of `Bank::CreateAccount` (which
// currently take no argument) to take an argument of type
// `const IInterestCalculator&`
#ifndef BANK_H_
#define BANK_H_
#include <list>
#include <memory>
class Account;
class Bank {
private:
std::list<std::shared_ptr<Account>> accounts_;
public:
std::shared_ptr<Account> CreateAccount();
void PayInterest();
};
#endif // BANK_H_
// TBD in this file:
// (1) add an argument or type `IInterestCalculator` to the
// implementation of `BankAccount::CreateAccount
// (2) forward that argument to `std::make_shared<Account>()`
// (which currently has no arguments)
#include "bank.h"
#include <ctime>
#include "account.h"
#include "logger.h"
std::shared_ptr<Account> Bank::CreateAccount()
{
auto account = std::make_shared<Account>();
accounts_.push_back(account);
Logger::Log("\nCreate account, number of accounts: ");
Logger::LogLine(accounts_.size());
return account;
}
void Bank::PayInterest()
{
for (auto& account : accounts_) {
const auto interest = account->CalculateInterest();
account->Deposit(interest);
}
Logger::Log("\nInterest paid on: ");
time_t current_time;
time(¤t_time);
auto time_string = ctime(¤t_time);
if (time_string != nullptr) {
Logger::LogLine(time_string);
}
}
#ifndef LOGGER_H_
#define LOGGER_H_
#include <iostream>
class Logger {
public:
template <class T>
static void Log(const T& message)
{
LogIntern(message, "");
}
template <class T>
static void LogLine(const T& message)
{
LogIntern(message, "\n");
}
template <class T>
static void LogIntern(const T& message, const char* additional_text)
{
std::cout << message << additional_text;
}
};
#endif // LOGGER_H_