Banking System
Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 104 of 104.
Challenge
EasyLet's build a Banking System that demonstrates the State pattern, inheritance, and smart pointer management. You'll create a system where accounts can be in different states (Active, Frozen, Closed), each with distinct behaviors for handling transactions.
You'll organize your code across six files:
AccountState.h: Define the State pattern infrastructure for account states.Create an abstract
AccountStatebase class with pure virtual methods:deposit(double amount)— returns true if deposit is allowed, false otherwisewithdraw(double amount)— returns true if withdrawal is allowed, false otherwisegetStateName()— returns the state name as a string
Implement three concrete states:
ActiveState: Allows both deposits and withdrawals, returns"Active"FrozenState: Allows deposits but rejects withdrawals, returns"Frozen"ClosedState: Rejects both deposits and withdrawals, returns"Closed"
Account.h: Build an account hierarchy with state management.Create a base
Accountclass with:- Account number (string), owner name, and balance
- A
std::unique_ptr<AccountState>to manage the current state deposit(double amount)— checks with state first, if allowed adds to balance and prints"Deposited [amount] to [accountNumber]", otherwise prints"Deposit rejected: account is [stateName]"withdraw(double amount)— checks with state, if allowed and sufficient funds, deducts and prints"Withdrew [amount] from [accountNumber]". If state rejects, print"Withdrawal rejected: account is [stateName]". If insufficient funds, print"Insufficient funds"freeze()andactivate()andclose()— change the account stategetInfo()— returns"[accountNumber] ([ownerName]): $[balance] - [stateName]"- Virtual
getAccountType()returning"Basic"
Create two derived account types:
SavingsAccount: Has a minimum balance requirement (passed to constructor). Override withdraw to also check if the withdrawal would drop below minimum — if so, print"Cannot go below minimum balance of [minimum]". Returns"Savings"for account type.CheckingAccount: Has an overdraft limit (passed to constructor). Allows withdrawals up to (balance + overdraftLimit). Returns"Checking"for account type.
Transaction.h: Model transactions as objects.Create a
Transactionclass that records:- Transaction type (string: "Deposit", "Withdrawal", "Transfer")
- Amount
- Account number involved
- Success status (bool)
Add a
getDescription()method returning"[type]: $[amount] on [accountNumber] - [Success/Failed]"Customer.h: Create a customer who owns multiple accounts.A
Customerhas a name, ID, and a vector ofstd::shared_ptr<Account>. Implement:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber)— returns the matching account or nullptrgetTotalBalance()— sums balances across all accountslistAccounts()— prints each account's info
Bank.h: Coordinate the banking operations.The
Bankclass stores customers and maintains a transaction history. Implement:addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber)— searches all customers for the accountprocessDeposit(const std::string& accountNumber, double amount)— finds account, performs deposit, records transactionprocessWithdrawal(const std::string& accountNumber, double amount)— finds account, performs withdrawal, records transactiongetTransactionCount()— returns total transactions processed
main.cpp: Demonstrate your banking system.Read four inputs:
- Customer details (format:
name,customerId) - Savings account details (format:
accountNumber,minBalance) - Operation 1 (format:
action,accountNumber,amountwhere action isdepositorwithdraw) - Operation 2 (format:
action,accountNumber,amountorfreeze,accountNumber)
Create the bank and customer. Create a savings account with the customer as owner and add it to the customer. Add the customer to the bank. Process both operations (if it's a freeze command, freeze the account then try a small withdrawal of $10 to demonstrate the state). Finally, print the customer's account list and the total transaction count as
"Transactions: [count]".- Customer details (format:
For example, with inputs Alice,C001, SAV001,100, deposit,SAV001,500, and withdraw,SAV001,200:
Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2With inputs Bob,C002, SAV002,50, deposit,SAV002,100, and freeze,SAV002:
Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2With inputs Carol,C003, SAV003,200, deposit,SAV003,250, and withdraw,SAV003,100:
Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2This challenge brings together the State pattern for managing account behaviors, inheritance for different account types, smart pointers for ownership relationships, and transaction tracking — all core concepts you've mastered throughout this course.
Try it yourself
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"
int main() {
// Read input 1: Customer details (format: name,customerId)
std::string customerInput;
std::getline(std::cin, customerInput);
// Read input 2: Savings account details (format: accountNumber,minBalance)
std::string accountInput;
std::getline(std::cin, accountInput);
// Read input 3: Operation 1 (format: action,accountNumber,amount)
std::string op1Input;
std::getline(std::cin, op1Input);
// Read input 4: Operation 2 (format: action,accountNumber,amount or freeze,accountNumber)
std::string op2Input;
std::getline(std::cin, op2Input);
// TODO: Parse customer details from customerInput
// Hint: Use find(',') to split the string
// TODO: Parse account details from accountInput
// TODO: Create the bank
// TODO: Create the customer
// TODO: Create a savings account with the customer as owner
// TODO: Add the account to the customer
// TODO: Add the customer to the bank
// TODO: Parse and process operation 1
// Format: action,accountNumber,amount (action is "deposit" or "withdraw")
// TODO: Parse and process operation 2
// Could be: action,accountNumber,amount OR freeze,accountNumber
// If freeze, freeze the account then try a withdrawal of $10
// TODO: Print the customer's account list
// TODO: Print transaction count as "Transactions: [count]"
return 0;
}
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesC++ Build & CompilationHeader Files & Source FilesNamespaces & ScopeIntroduction to OOP in C++Classes vs ObjectsThe 'this' PointerMethods (Member Functions)Attributes (Data Members)Ctors & Dtors BasicsRecap - Simple Calculator4Class Properties
Instance vs Static MembersGetters and SettersConst Member FunctionsMutable KeywordStatic Methods and VariablesFriend Functions & ClassesRecap - Bank Account Manager7Inheritance
Basic InheritanceInheritance Access LevelsCtor & Dtor Call OrderMethod OverridingVirtual Functions & VTableMultiple InheritanceVirtual InheritanceRecap - Employee Hierarchy2Memory Management
Stack vs Heap MemoryPointers and ReferencesDynamic Memory (new/delete)Smart Pointers in C++RAII in C++Recap - Dynamic Array Manager5Encapsulation
Access Specifiers in C++Access Specifiers In DepthInformation HidingStruct vs ClassNested & Inner ClassesRecap - Student Records System8Polymorphism
Compile vs Runtime PolymorphFunction OverloadingVirtual Functions RevisitedPure Virtual FunctionsAbstract ClassesInterface Design in C++Dynamic Casting & RTTIRecap - Shape Calculator3Constructors & Destructors
Default ConstructorParameterized ConstructorCopy ConstructorMove ConstructorConstructor Init ListsDelegating ConstructorsDestructor Deep DiveRule of Three / Five / ZeroRecap - String Class6Operator Overloading
Intro to Operator OverloadArithmetic Operator OverloadComparison Operator OverloadStream OperatorsAssignment Operator Overload[] and () Operator OverloadType Conversion OperatorsRecap - Matrix Class9Templates
Function TemplatesClass TemplatesTemplate SpecializationVariadic TemplatesSFINAE & Type Traits BasicsRecap - Generic Container