Menu
Coddy logo textTech

Sistema Bancário

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 104 de 104.

challenge icon

Desafio

Fácil

Vamos construir um Sistema Bancário que demonstra o padrão State, herança e gerenciamento de smart pointers. Você criará um sistema onde as contas podem estar em diferentes estados (Active, Frozen, Closed), cada um com comportamentos distintos para lidar com transações.

Você organizará seu código em seis arquivos:

  • AccountState.h: Define a infraestrutura do padrão State para os estados da conta.

    Crie uma classe base abstrata AccountState com métodos virtuais puros:

    • deposit(double amount) — retorna true se o depósito for permitido, false caso contrário
    • withdraw(double amount) — retorna true se o saque for permitido, false caso contrário
    • getStateName() — retorna o nome do estado como uma string

    Implemente três estados concretos:

    • ActiveState: Permite tanto depósitos quanto saques, retorna "Active"
    • FrozenState: Permite depósitos, mas rejeita saques, retorna "Frozen"
    • ClosedState: Rejeita tanto depósitos quanto saques, retorna "Closed"
  • Account.h: Construa uma hierarquia de contas com gerenciamento de estado.

    Crie uma classe base Account com:

    • Número da conta (string), nome do proprietário e saldo
    • Um std::unique_ptr<AccountState> para gerenciar o estado atual
    • deposit(double amount) — verifica primeiro com o estado; se permitido, adiciona ao saldo e imprime "Deposited [amount] to [accountNumber]", caso contrário, imprime "Deposit rejected: account is [stateName]"
    • withdraw(double amount) — verifica com o estado; se permitido e houver fundos suficientes, deduz e imprime "Withdrew [amount] from [accountNumber]". Se o estado rejeitar, imprime "Withdrawal rejected: account is [stateName]". Se houver fundos insuficientes, imprime "Insufficient funds"
    • freeze(), activate() e close() — alteram o estado da conta
    • getInfo() — retorna "[accountNumber] ([ownerName]): $[balance] - [stateName]"
    • getAccountType() virtual retornando "Basic"

    Crie dois tipos de conta derivados:

    • SavingsAccount: Possui um requisito de saldo mínimo (passado ao construtor). Sobrescreva withdraw para também verificar se o saque cairia abaixo do mínimo — se sim, imprima "Cannot go below minimum balance of [minimum]". Retorna "Savings" para o tipo de conta.
    • CheckingAccount: Possui um limite de cheque especial (passado ao construtor). Permite saques até (saldo + overdraftLimit). Retorna "Checking" para o tipo de conta.
  • Transaction.h: Modele transações como objetos.

    Crie uma classe Transaction que registre:

    • Tipo de transação (string: "Deposit", "Withdrawal", "Transfer")
    • Valor
    • Número da conta envolvida
    • Status de sucesso (bool)

    Adicione um método getDescription() retornando "[type]: $[amount] on [accountNumber] - [Success/Failed]"

  • Customer.h: Crie um cliente que possui várias contas.

    Um Customer tem um nome, ID e um vetor de std::shared_ptr<Account>. Implemente:

    • addAccount(std::shared_ptr<Account> account)
    • getAccount(const std::string& accountNumber) — retorna a conta correspondente ou nullptr
    • getTotalBalance() — soma os saldos de todas as contas
    • listAccounts() — imprime as informações de cada conta
  • Bank.h: Coordine as operações bancárias.

    A classe Bank armazena clientes e mantém um histórico de transações. Implemente:

    • addCustomer(std::shared_ptr<Customer> customer)
    • findAccount(const std::string& accountNumber) — pesquisa a conta em todos os clientes
    • processDeposit(const std::string& accountNumber, double amount) — encontra a conta, realiza o depósito, registra a transação
    • processWithdrawal(const std::string& accountNumber, double amount) — encontra a conta, realiza o saque, registra a transação
    • getTransactionCount() — retorna o total de transações processadas
  • main.cpp: Demonstre seu sistema bancário.

    Leia quatro entradas:

    1. Detalhes do cliente (formato: name,customerId)
    2. Detalhes da conta poupança (formato: accountNumber,minBalance)
    3. Operação 1 (formato: action,accountNumber,amount onde action é deposit ou withdraw)
    4. Operação 2 (formato: action,accountNumber,amount ou freeze,accountNumber)

    Crie o banco e o cliente. Crie uma conta poupança com o cliente como proprietário e adicione-a ao cliente. Adicione o cliente ao banco. Processe ambas as operações (se for um comando freeze, congele a conta e tente um pequeno saque de $10 para demonstrar o estado). Por fim, imprima a lista de contas do cliente e a contagem total de transações como "Transactions: [count]".

Por exemplo, com as entradas Alice,C001, SAV001,100, deposit,SAV001,500 e withdraw,SAV001,200:

Deposited 500 to SAV001
Withdrew 200 from SAV001
SAV001 (Alice): $300 - Active
Transactions: 2

Com as entradas Bob,C002, SAV002,50, deposit,SAV002,100 e freeze,SAV002:

Deposited 100 to SAV002
Withdrawal rejected: account is Frozen
SAV002 (Bob): $100 - Frozen
Transactions: 2

Com as entradas Carol,C003, SAV003,200, deposit,SAV003,250 e withdraw,SAV003,100:

Deposited 250 to SAV003
Cannot go below minimum balance of 200
SAV003 (Carol): $250 - Active
Transactions: 2

Este desafio reúne o padrão State para gerenciar comportamentos de conta, herança para diferentes tipos de conta, smart pointers para relações de propriedade e rastreamento de transações — todos conceitos fundamentais que você dominou ao longo deste curso.

Experimente você mesmo

#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include "Bank.h"

int main() {
    // Ler entrada 1: Detalhes do cliente (formato: name,customerId)
    std::string customerInput;
    std::getline(std::cin, customerInput);
    
    // Ler entrada 2: Detalhes da conta poupança (formato: accountNumber,minBalance)
    std::string accountInput;
    std::getline(std::cin, accountInput);
    
    // Ler entrada 3: Operação 1 (formato: action,accountNumber,amount)
    std::string op1Input;
    std::getline(std::cin, op1Input);
    
    // Ler entrada 4: Operação 2 (formato: action,accountNumber,amount ou freeze,accountNumber)
    std::string op2Input;
    std::getline(std::cin, op2Input);
    
    // TODO: Analisar detalhes do cliente a partir de customerInput
    // Dica: Use find(',') para dividir a string
    
    // TODO: Analisar detalhes da conta a partir de accountInput
    
    // TODO: Criar o banco
    
    // TODO: Criar o cliente
    
    // TODO: Criar uma conta poupança com o cliente como proprietário
    
    // TODO: Adicionar a conta ao cliente
    
    // TODO: Adicionar o cliente ao banco
    
    // TODO: Analisar e processar a operação 1
    // Formato: action,accountNumber,amount (action é "deposit" ou "withdraw")
    
    // TODO: Analisar e processar a operação 2
    // Pode ser: action,accountNumber,amount OU freeze,accountNumber
    // Se freeze, congele a conta e tente um saque de $10
    
    // TODO: Imprimir a lista de contas do cliente
    
    // TODO: Imprimir a contagem de transações como "Transactions: [count]"
    
    return 0;
}

Todas as lições de Programação Orientada a Objetos