Menu
Coddy logo textTech

Bankensystem

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 104 von 104.

challenge icon

Aufgabe

Einfach

Erstellen wir ein Banksystem, das das Zustandsmuster, Vererbung und die Verwaltung intelligenter Zeiger demonstriert. Du erstellst ein System, in dem sich Konten in verschiedenen Zuständen (Active, Frozen, Closed) befinden können, wobei jeder Zustand ein eigenes Verhalten bei der Verarbeitung von Transaktionen aufweist.

Du organisierst deinen Code über sechs Dateien:

  • AccountState.h: Definiert die Infrastruktur des Zustandsmusters für Kontozustände.

    Erstelle eine abstrakte Basisklasse AccountState mit rein virtuellen Methoden:

    • deposit(double amount): gibt true zurück, wenn eine Einzahlung zulässig ist, andernfalls false
    • withdraw(double amount): gibt true zurück, wenn eine Auszahlung zulässig ist, andernfalls false
    • getStateName(): gibt den Namen des Zustands als Zeichenkette zurück

    Implementiere drei konkrete Zustände:

    • ActiveState: Erlaubt sowohl Einzahlungen als auch Auszahlungen und gibt "Active" zurück
    • FrozenState: Erlaubt Einzahlungen, lehnt aber Auszahlungen ab und gibt "Frozen" zurück
    • ClosedState: Lehnt sowohl Einzahlungen als auch Auszahlungen ab und gibt "Closed" zurück
  • Account.h: Erstellt eine Kontohierarchie mit Zustandsverwaltung.

    Erstelle eine Basisklasse Account mit:

    • Kontonummer (Zeichenkette), Name des Kontoinhabers und Kontostand
    • Einem std::unique_ptr<AccountState> zur Verwaltung des aktuellen Zustands
    • deposit(double amount): Prüft zuerst den Zustand; wenn die Einzahlung zulässig ist, wird der Betrag zum Kontostand addiert und "Deposited [amount] to [accountNumber]" ausgegeben, andernfalls "Deposit rejected: account is [stateName]"
    • withdraw(double amount): Prüft den Zustand; wenn die Auszahlung zulässig ist und ausreichende Mittel vorhanden sind, wird der Betrag abgezogen und "Withdrew [amount] from [accountNumber]" ausgegeben. Wenn der Zustand die Auszahlung ablehnt, wird "Withdrawal rejected: account is [stateName]" ausgegeben. Wenn die Mittel nicht ausreichen, wird "Insufficient funds" ausgegeben
    • freeze(), activate() und close(): Ändern den Kontozustand
    • getInfo(): Gibt "[accountNumber] ([ownerName]): $[balance] - [stateName]" zurück
    • Virtuelles getAccountType(), das "Basic" zurückgibt

    Erstelle zwei abgeleitete Kontotypen:

    • SavingsAccount: Besitzt eine Mindestguthabenanforderung, die an den Konstruktor übergeben wird. Überschreibe withdraw, sodass zusätzlich geprüft wird, ob die Auszahlung den Kontostand unter das Mindestguthaben senken würde. Falls dies der Fall ist, gib "Cannot go below minimum balance of [minimum]" aus. Gibt "Savings" als Kontotyp zurück.
    • CheckingAccount: Besitzt ein Überziehungslimit, das an den Konstruktor übergeben wird. Erlaubt Auszahlungen bis zur Höhe von (Kontostand + overdraftLimit). Gibt "Checking" als Kontotyp zurück.
  • Transaction.h: Modelliert Transaktionen als Objekte.

    Erstelle eine Klasse Transaction, die Folgendes erfasst:

    • Transaktionstyp (Zeichenkette: "Deposit", "Withdrawal", "Transfer")
    • Betrag
    • Beteiligte Kontonummer
    • Erfolgsstatus (bool)

    Füge eine Methode getDescription() hinzu, die "[type]: $[amount] on [accountNumber] - [Success/Failed]" zurückgibt

  • Customer.h: Erstellt einen Kunden, der mehrere Konten besitzt.

    Ein Customer besitzt einen Namen, eine ID und einen Vektor aus std::shared_ptr<Account>. Implementiere:

    • addAccount(std::shared_ptr<Account> account)
    • getAccount(const std::string& accountNumber): Gibt das passende Konto oder nullptr zurück
    • getTotalBalance(): Summiert die Kontostände aller Konten
    • listAccounts(): Gibt die Informationen zu jedem Konto aus
  • Bank.h: Koordiniert die Bankgeschäfte.

    Die Klasse Bank speichert Kunden und verwaltet eine Transaktionshistorie. Implementiere:

    • addCustomer(std::shared_ptr<Customer> customer)
    • findAccount(const std::string& accountNumber): Durchsucht alle Kunden nach dem Konto
    • processDeposit(const std::string& accountNumber, double amount): Findet das Konto, führt die Einzahlung durch und erfasst die Transaktion
    • processWithdrawal(const std::string& accountNumber, double amount): Findet das Konto, führt die Auszahlung durch und erfasst die Transaktion
    • getTransactionCount(): Gibt die Gesamtzahl der verarbeiteten Transaktionen zurück
  • main.cpp: Demonstriert dein Banksystem.

    Lies vier Eingaben ein:

    1. Kundendaten (Format: name,customerId)
    2. Daten des Sparkontos (Format: accountNumber,minBalance)
    3. Operation 1 (Format: action,accountNumber,amount, wobei action deposit oder withdraw ist)
    4. Operation 2 (Format: action,accountNumber,amount oder freeze,accountNumber)

    Erstelle die Bank und den Kunden. Erstelle ein Sparkonto mit dem Kunden als Inhaber und füge es dem Kunden hinzu. Füge den Kunden zur Bank hinzu. Verarbeite beide Operationen (wenn es sich um einen freeze-Befehl handelt, friere das Konto ein und versuche anschließend eine kleine Auszahlung von $10, um den Zustand zu demonstrieren). Gib schließlich die Kontoliste des Kunden und die Gesamtzahl der Transaktionen als "Transactions: [count]" aus.

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: 2

Mit 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: 2

Mit 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: 2

Diese Herausforderung verbindet das Zustandsmuster zur Verwaltung des Kontoverhaltens, Vererbung für verschiedene Kontotypen, intelligente Zeiger für Besitzverhältnisse und die Nachverfolgung von Transaktionen – alles zentrale Konzepte, die du im Laufe dieses Kurses gemeistert hast.

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 Inhaber erstellen
    
    // TODO: Das Konto zum Kunden hinzufügen
    
    // TODO: Den Kunden zur Bank hinzufügen
    
    // TODO: Operation 1 parsen und verarbeiten
    // Format: action,accountNumber,amount (action ist "deposit" oder "withdraw")
    
    // TODO: Operation 2 parsen und verarbeiten
    // Könnte sein: action,accountNumber,amount ODER freeze,accountNumber
    // Bei freeze das Konto einfrieren und dann eine Abhebung von $10 versuchen
    
    // TODO: Kontoliste des Kunden ausgeben
    
    // TODO: Print transaction count as "Transactions: [count]"
    
    return 0;
}

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C++-Compiler