System bankowy
Część sekcji Programowanie obiektowe ścieżki C++ w Coddy. Lekcja 104 z 104.
Wyzwanie
ŁatwyZbudujmy system bankowy, który demonstruje wzorzec State, dziedziczenie i zarządzanie inteligentnymi wskaźnikami. Stworzysz system, w którym konta mogą znajdować się w różnych stanach (Active, Frozen, Closed), z których każdy ma inne zachowanie podczas obsługi transakcji.
Rozmieścisz swój kod w sześciu plikach:
AccountState.h: Zdefiniuj infrastrukturę wzorca State dla stanów konta.Utwórz abstrakcyjną klasę bazową
AccountStatez czysto wirtualnymi metodami:deposit(double amount): zwraca true, jeśli wpłata jest dozwolona, w przeciwnym razie falsewithdraw(double amount): zwraca true, jeśli wypłata jest dozwolona, w przeciwnym razie falsegetStateName(): zwraca nazwę stanu jako ciąg znaków
Zaimplementuj trzy konkretne stany:
ActiveState: Zezwala na wpłaty i wypłaty, zwraca"Active"FrozenState: Zezwala na wpłaty, ale odrzuca wypłaty, zwraca"Frozen"ClosedState: Odrzuca wpłaty i wypłaty, zwraca"Closed"
Account.h: Zbuduj hierarchię kont z zarządzaniem stanem.Utwórz bazową klasę
Accountzawierającą:- Numer konta (ciąg znaków), imię i nazwisko właściciela oraz saldo
std::unique_ptr<AccountState>do zarządzania bieżącym stanemdeposit(double amount): najpierw sprawdza stan; jeśli wpłata jest dozwolona, dodaje kwotę do salda i wypisuje"Deposited [amount] to [accountNumber]", w przeciwnym razie wypisuje"Deposit rejected: account is [stateName]"withdraw(double amount): sprawdza stan; jeśli wypłata jest dozwolona i są wystarczające środki, odejmuje kwotę i wypisuje"Withdrew [amount] from [accountNumber]". Jeśli stan odrzuca wypłatę, wypisuje"Withdrawal rejected: account is [stateName]". Jeśli brakuje środków, wypisuje"Insufficient funds"freeze(),activate()iclose(): zmieniają stan kontagetInfo(): zwraca"[accountNumber] ([ownerName]): $[balance] - [stateName]"- Wirtualna metoda
getAccountType()zwracająca"Basic"
Utwórz dwa typy kont pochodne:
SavingsAccount: Ma wymagane minimalne saldo (przekazywane do konstruktora). Nadpisz metodę withdraw, aby dodatkowo sprawdzała, czy wypłata obniży saldo poniżej minimum; jeśli tak, wypisz"Cannot go below minimum balance of [minimum]". Zwraca"Savings"jako typ konta.CheckingAccount: Ma limit debetu (przekazywany do konstruktora). Zezwala na wypłaty do wysokości (salda + overdraftLimit). Zwraca"Checking"jako typ konta.
Transaction.h: Modeluj transakcje jako obiekty.Utwórz klasę
Transaction, która zapisuje:- Typ transakcji (ciąg znaków: "Deposit", "Withdrawal", "Transfer")
- Kwotę
- Numer konta, którego dotyczy transakcja
- Status powodzenia (bool)
Dodaj metodę
getDescription(), która zwraca"[type]: $[amount] on [accountNumber] - [Success/Failed]"Customer.h: Utwórz klienta, który posiada wiele kont.Customerma imię i nazwisko, ID oraz wektor elementówstd::shared_ptr<Account>. Zaimplementuj:addAccount(std::shared_ptr<Account> account)getAccount(const std::string& accountNumber): zwraca pasujące konto lub nullptrgetTotalBalance(): sumuje salda wszystkich kontlistAccounts(): wypisuje informacje o każdym koncie
Bank.h: Koordynuj operacje bankowe.Klasa
Bankprzechowuje klientów i prowadzi historię transakcji. Zaimplementuj:addCustomer(std::shared_ptr<Customer> customer)findAccount(const std::string& accountNumber): wyszukuje konto u wszystkich klientówprocessDeposit(const std::string& accountNumber, double amount): znajduje konto, wykonuje wpłatę i zapisuje transakcjęprocessWithdrawal(const std::string& accountNumber, double amount): znajduje konto, wykonuje wypłatę i zapisuje transakcjęgetTransactionCount(): zwraca łączną liczbę przetworzonych transakcji
main.cpp: Zademonstruj działanie systemu bankowego.Wczytaj cztery dane wejściowe:
- Dane klienta (format:
name,customerId) - Dane konta oszczędnościowego (format:
accountNumber,minBalance) - Operacja 1 (format:
action,accountNumber,amount, gdzie action todepositlubwithdraw) - Operacja 2 (format:
action,accountNumber,amountlubfreeze,accountNumber)
Utwórz bank i klienta. Utwórz konto oszczędnościowe, którego właścicielem będzie klient, i dodaj je do klienta. Dodaj klienta do banku. Wykonaj obie operacje (jeśli jest to polecenie freeze, zamroź konto, a następnie spróbuj dokonać niewielkiej wypłaty w wysokości $10, aby zademonstrować działanie stanu). Na koniec wypisz listę kont klienta i łączną liczbę transakcji w formacie
"Transactions: [count]".- Dane klienta (format:
Na przykład dla danych wejściowych Alice,C001, SAV001,100, deposit,SAV001,500 i withdraw,SAV001,200:
Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2Dla danych wejściowych Bob,C002, SAV002,50, deposit,SAV002,100 i freeze,SAV002:
Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2Dla danych wejściowych Carol,C003, SAV003,200, deposit,SAV003,250 i withdraw,SAV003,100:
Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2To wyzwanie łączy wzorzec State do zarządzania zachowaniem kont, dziedziczenie dla różnych typów kont, inteligentne wskaźniki do relacji własności oraz śledzenie transakcji — wszystkie kluczowe koncepcje, które opanowałeś w trakcie tego kursu.
Spróbuj swoich sił
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"
int main() {
// Odczytaj dane wejściowe 1: dane klienta (format: name,customerId)
std::string customerInput;
std::getline(std::cin, customerInput);
// Odczytaj dane wejściowe 2: dane konta oszczędnościowego (format: accountNumber,minBalance)
std::string accountInput;
std::getline(std::cin, accountInput);
// Odczytaj dane wejściowe 3: operacja 1 (format: action,accountNumber,amount)
std::string op1Input;
std::getline(std::cin, op1Input);
// Odczytaj dane wejściowe 4: operacja 2 (format: action,accountNumber,amount lub freeze,accountNumber)
std::string op2Input;
std::getline(std::cin, op2Input);
// TODO: Odczytaj dane klienta z customerInput
// Wskazówka: użyj find(',') do podzielenia ciągu znaków
// TODO: Odczytaj dane konta z accountInput
// TODO: Utwórz bank
// TODO: Utwórz klienta
// TODO: Utwórz konto oszczędnościowe, którego właścicielem jest klient
// TODO: Dodaj konto do klienta
// TODO: Dodaj klienta do banku
// TODO: Przeanalizuj i przetwórz operację 1
// Format: action,accountNumber,amount (action to "deposit" lub "withdraw")
// TODO: Przeanalizuj i przetwórz operację 2
// Możliwe formaty: action,accountNumber,amount lub freeze,accountNumber
// Jeśli podano freeze, zablokuj konto, a następnie spróbuj wypłacić $10
// TODO: Wyświetl listę kont klienta
// TODO: Wyświetl liczbę transakcji w postaci "Transactions: [count]"
return 0;
}
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneBudowanie i kompilacja C++Pliki nagłówkowe i pliki źródłowePrzestrzenie nazw i zakresWprowadzenie do programowania obiektowego w C++Klasy a obiektyWskaźnik „this”Metody (funkcje składowe)Atrybuty (składowe danych)Podstawy konstruktorów i destruktorówPowtórzenie – prosty kalkulator4Właściwości klas
Elementy instancji a elementy statyczneGettery i setteryStałe funkcje składoweSłowo kluczowe mutableMetody i zmienne statyczneFunkcje i klasy zaprzyjaźnionePodsumowanie – menedżer konta bankowego7Dziedziczenie
Podstawy dziedziczeniaPoziomy dostępu w dziedziczeniuKolejność wywołań konstruktora i destruktoraNadpisywanie metodFunkcje wirtualne i VTableWielokrotne dziedziczenieDziedziczenie wirtualnePowtórzenie — hierarchia pracowników2Zarządzanie pamięcią
Pamięć stosu a stertyWskaźniki i referencjePamięć dynamiczna (new/delete)Inteligentne wskaźniki w C++RAII w C++Podsumowanie — menedżer tablicy dynamicznej5Hermetyzacja
Specyfikatory dostępu w C++Specyfikatory dostępu — szczegółowoUkrywanie informacjiStruktura a klasaKlasy zagnieżdżone i wewnętrznePodsumowanie — system ewidencji studentów8Polimorfizm
Polimorfizm czasu kompilacji i wykonaniaPrzeciążanie funkcjiFunkcje wirtualne — powtórkaCzysto wirtualne funkcjeKlasy abstrakcyjneProjektowanie interfejsów w C++Rzutowanie dynamiczne i RTTIPodsumowanie — kalkulator kształtów3Konstruktory i destruktory
Konstruktor domyślnyKonstruktor z parametramiKonstruktor kopiującyKonstruktor przenoszącyListy inicjalizacyjne konstruktoraKonstruktory delegująceDestruktor — szczegółowe omówienieZasada trzech / pięciu / zeraPodsumowanie — klasa String6Przeciążanie operatorów
Wprowadzenie do przeciążania operatorówPrzeciążanie operatorów arytmetycznychPrzeciążanie operatorów porównaniaOperatory strumieniowePrzeciążanie operatora przypisaniaPrzeciążanie operatorów [] i ()Operatory konwersji typówPodsumowanie — klasa Matrix9Szablony
Szablony funkcjiSzablony klasSpecjalizacja szablonówSzablony wariadycznePodstawy SFINAE i cech typówPodsumowanie — kontener generycznyPoćwicz samodzielnie: Kompilator C++ online