Bankensystem
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 104 von 104.
Aufgabe
EinfachLassen Sie uns ein Bankensystem bauen, das das State-Pattern, Vererbung und Smart-Pointer-Management demonstriert. Sie werden ein System erstellen, in dem Konten in verschiedenen Zuständen sein können (Active, Frozen, Closed), wobei jeder Zustand ein unterschiedliches Verhalten bei der Verarbeitung von Transaktionen aufweist.
Sie werden Ihren Code auf sechs Dateien verteilen:
AccountState.h: Definieren Sie die Infrastruktur für das State-Pattern der Kontozustände.Erstellen Sie eine abstrakte Basisklasse
AccountStatemit rein virtuellen Methoden:deposit(double amount)— gibt true zurück, wenn eine Einzahlung erlaubt ist, andernfalls falsewithdraw(double amount)— gibt true zurück, wenn eine Auszahlung erlaubt ist, andernfalls falsegetStateName()— gibt den Namen des Zustands als String zurück
Implementieren Sie drei konkrete Zustände:
ActiveState: Erlaubt sowohl Einzahlungen als auch Auszahlungen, gibt"Active"zurückFrozenState: Erlaubt Einzahlungen, lehnt aber Auszahlungen ab, gibt"Frozen"zurückClosedState: Lehnt sowohl Einzahlungen als auch Auszahlungen ab, gibt"Closed"zurück
Account.h: Erstellen Sie eine Kontohierarchie mit Zustandsverwaltung.Erstellen Sie eine Basisklasse
Accountmit:- Kontonummer (String), Name des Inhabers und Kontostand
- Einem
std::unique_ptr<AccountState>zur Verwaltung des aktuellen Zustands deposit(double amount)— prüft zuerst den Zustand; falls erlaubt, wird der Betrag zum Kontostand addiert und"Deposited [amount] to [accountNumber]"ausgegeben, andernfalls wird"Deposit rejected: account is [stateName]"ausgegebenwithdraw(double amount)— prüft den Zustand; falls erlaubt und ausreichend Guthaben vorhanden ist, wird der Betrag abgezogen und"Withdrew [amount] from [accountNumber]"ausgegeben. Wenn der Zustand ablehnt, geben Sie"Withdrawal rejected: account is [stateName]"aus. Bei unzureichendem Guthaben geben Sie"Insufficient funds"ausfreeze(),activate()undclose()— ändern den KontozustandgetInfo()— gibt"[accountNumber] ([ownerName]): $[balance] - [stateName]"zurück- Virtuelle Methode
getAccountType(), die"Basic"zurückgibt
Erstellen Sie zwei abgeleitete Kontotypen:
SavingsAccount: Hat eine Mindestguthaben-Anforderung (wird dem Konstruktor übergeben). Überschreiben Sie withdraw, um zusätzlich zu prüfen, ob die Auszahlung das Mindestguthaben unterschreiten würde — falls ja, geben Sie"Cannot go below minimum balance of [minimum]"aus. Gibt"Savings"als Kontotyp zurück.CheckingAccount: Hat ein Überlimit (wird dem Konstruktor übergeben). Erlaubt Auszahlungen bis zu (balance + overdraftLimit). Gibt"Checking"als Kontotyp zurück.
Transaction.h: Modellieren Sie Transaktionen als Objekte.Erstellen Sie eine Klasse
Transaction, die Folgendes aufzeichnet:- Transaktionstyp (String: "Deposit", "Withdrawal", "Transfer")
- Betrag
- Beteiligte Kontonummer
- Erfolgsstatus (bool)
Fügen Sie eine Methode
getDescription()hinzu, die"[type]: $[amount] on [accountNumber] - [Success/Failed]"zurückgibtCustomer.h: Erstellen Sie einen Kunden, der mehrere Konten besitzt.Ein
Customerhat einen Namen, eine ID und einen Vektor vonstd::shared_ptr<Account>. Implementieren Sie:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber)— gibt das passende Konto oder nullptr zurückgetTotalBalance()— summiert die Guthaben aller KontenlistAccounts()— gibt die Informationen jedes Kontos aus
Bank.h: Koordinieren Sie die Bankgeschäfte.Die Klasse
Bankspeichert Kunden und führt eine Transaktionshistorie. Implementieren Sie:addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber)— durchsucht alle Kunden nach dem KontoprocessDeposit(const std::string& accountNumber, double amount)— findet das Konto, führt die Einzahlung aus, zeichnet die Transaktion aufprocessWithdrawal(const std::string& accountNumber, double amount)— findet das Konto, führt die Auszahlung aus, zeichnet die Transaktion aufgetTransactionCount()— gibt die Gesamtzahl der verarbeiteten Transaktionen zurück
main.cpp: Demonstrieren Sie Ihr Bankensystem.Lesen Sie vier Eingaben ein:
- Kundendetails (Format:
name,customerId) - Details zum Sparkonto (Format:
accountNumber,minBalance) - Operation 1 (Format:
action,accountNumber,amountwobei actiondepositoderwithdrawist) - Operation 2 (Format:
action,accountNumber,amountoderfreeze,accountNumber)
Erstellen Sie die Bank und den Kunden. Erstellen Sie ein Sparkonto mit dem Kunden als Inhaber und fügen Sie es dem Kunden hinzu. Fügen Sie den Kunden der Bank hinzu. Verarbeiten Sie beide Operationen (wenn es ein freeze-Befehl ist, frieren Sie das Konto ein und versuchen Sie dann eine kleine Auszahlung von $10, um den Zustand zu demonstrieren). Geben Sie abschließend die Kontoliste des Kunden und die Gesamtzahl der Transaktionen als
"Transactions: [count]"aus.- Kundendetails (Format:
Zum Beispiel, mit den Eingaben Alice,C001, SAV001,100, deposit,SAV001,500 und withdraw,SAV001,200:
Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2Mit den Eingaben Bob,C002, SAV002,50, deposit,SAV002,100 und freeze,SAV002:
Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2Mit den Eingaben Carol,C003, SAV003,200, deposit,SAV003,250 und withdraw,SAV003,100:
Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2Diese Herausforderung vereint das State-Pattern zur Verwaltung von Kontoverhalten, Vererbung für verschiedene Kontotypen, Smart Pointer für Besitzverhältnisse und Transaktionsverfolgung — alles Kernkonzepte, die Sie in diesem Kurs gemeistert haben.
Probier es selbst
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"
int main() {
// Eingabe 1 lesen: Kundendetails (Format: name,customerId)
std::string customerInput;
std::getline(std::cin, customerInput);
// Eingabe 2 lesen: Sparkontodetails (Format: accountNumber,minBalance)
std::string accountInput;
std::getline(std::cin, accountInput);
// Eingabe 3 lesen: Operation 1 (Format: action,accountNumber,amount)
std::string op1Input;
std::getline(std::cin, op1Input);
// Eingabe 4 lesen: Operation 2 (Format: action,accountNumber,amount oder freeze,accountNumber)
std::string op2Input;
std::getline(std::cin, op2Input);
// TODO: Kundendetails aus customerInput parsen
// Hinweis: Verwende find(','), um den String zu teilen
// TODO: Kontodetails aus accountInput parsen
// TODO: Die Bank erstellen
// TODO: Den Kunden erstellen
// TODO: Ein Sparkonto mit dem Kunden als Besitzer erstellen
// TODO: Das Konto dem Kunden hinzufügen
// TODO: Den Kunden der Bank hinzufügen
// TODO: Operation 1 parsen und verarbeiten
// Format: action,accountNumber,amount (Aktion ist "deposit" oder "withdraw")
// TODO: Operation 2 parsen und verarbeiten
// Mögliche Formate: action,accountNumber,amount ODER freeze,accountNumber
// Falls freeze, das Konto sperren und dann eine Abhebung von $10 versuchen
// TODO: Die Kontoliste des Kunden ausgeben
// TODO: Transaktionsanzahl als "Transactions: [count]" ausgeben
return 0;
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container