Abhishek Anant Singh
Abhishek Anant Singh

Reputation: 41

How to make a method update the attribute of an class in C++

I wanted to make a somewhat basic simulation of different types of Account in the bank. I have made a class Account and Savings_Account & Checking_Account is an Account and Trust_Account is a Savings_Account. I have a problem only in the Account class so this question will only focus on the Account class. I have only two attributes in the Account class: std::string name and double balance. I also have two methods in the Account class: bool deposit(double amount) and bool withdraw(double amount). The problem: when I deposit(amount) it works fine and it updates the balance but when I withdraw(amount) the updated balance does not reflect and amount withdraws from the default balance.

My code:

Accounts.hpp

#pragma once

#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::vector;

//The Account class(parent class)
class Account{
    friend std::ostream &operator<<(std::ostream &os, const Account &account);  //Outputs the object
private:
    static constexpr const char *def_name = "Empty";              //Default name
    static constexpr double def_balance = 0.0;                    //Default balance
protected:
    string name{};                                          //Name of the Account holder
    double balance{};                                       //Balance of the Account
public:
    Account(string n = def_name, double b = def_balance);        //Constructor
    bool deposit(double amount);                                 //Method to deposit 
    bool withdraw(double amount);                                //Method to withdraw
};

Accounts.cpp

#include "Accounts.hpp"

//Construtor
Account::Account(string n, double b) 
    :name{n}, balance{b} {
}

//Method for deposit
bool Account::deposit(double amount) {
    if (amount < 0)
        return false;
    else {
        balance += amount;
        return true;
    }
}

//Method for withdraw
bool Account::withdraw(double amount) {
    if (balance - amount >= 0) {
        balance -= amount;
        return true;
    } else {
        return false;
    }
}

//Outputs the object
std::ostream &operator<<(std::ostream &os, const Account &account) {
    os << "A-> " << account.name << " : " << account.balance << endl;
    return os;
}

I have also made some utility functions that allows me to display,deposit and withdraw from all Account in the vector<Account> acnt

AccountsUtil.hpp

#include "Accounts.hpp"

/* Util functions for Account */
//Displays all the Account
void display(const vector<Account> &a);

//Deposits to all the Account
void deposit(vector<Account> &a, double bl);

//Withdraws from all the Account
void withdraw(vector<Account> &a, double bl);

AccountsUtil.cpp

/* Utils for Account */
//Displays all the Account
void display(const vector<Account> &a) {
    cout << "--->Accounts----------------" << endl;
    for (const auto &i: a)
        cout << i << endl;
    cout << "=====================================\n" << endl;
}

//Deposits to all the Account
void deposit(vector<Account> &a, double bl) {
    cout << "Depositing for Account=========================" << endl;
    for (auto i: a) {
        if (i.deposit(bl))
            cout << "Deposit successful for:=> " << i << endl;
        else   
            cout << "Deposit failed for:=> " << i << endl;
    }
    cout << "==============================================\n" << endl;
}

//Withdraws from all the Account
void withdraw(vector<Account> &a, double bl) {
    cout << "Withdrawing for Account============================" << endl;
    for (auto i: a) {
        if (i.withdraw(bl))
            cout << "Withdraw successful for :=> " << i << endl;
        else    
            cout << "Withdraw failed for :=> " << i << endl;
    }
    cout << "===================================================\n" << endl;
}

main.cpp

#include "AccountsUtil.hpp" 

int main() {
    vector<Account> acnt;
    acnt.push_back(Account {});
    acnt.push_back(Account {"Tony"});
    acnt.push_back(Account {"Steve", 2000});
    acnt.push_back(Account {"Thor", 5000});

    display(acnt);
    deposit(acnt,1000);
    withdraw(acnt,3000);

    return 0;
}

My output(wrong/unexpected)

--->Accounts----------------
A-> Empty : 0

A-> Tony : 0

A-> Steve : 2000

A-> Thor : 5000

=====================================

Depositing for Account=========================
Deposit successful for:=> A-> Empty : 1000

Deposit successful for:=> A-> Tony : 1000

Deposit successful for:=> A-> Steve : 3000

Deposit successful for:=> A-> Thor : 6000

==============================================

Withdrawing for Account============================
Withdraw failed for :=> A-> Empty : 0

Withdraw failed for :=> A-> Tony : 0

Withdraw failed for :=> A-> Steve : 2000

Withdraw successful for :=> A-> Thor : 2000

===================================================

As it is clearly visible that the balance was updated while depositing but while withdrawing the default balance was used. Ex: After depositing the balance of Steve was 3000 so withdrawing 3000 from Steve should have worked fine but withdrawal failed for him showing that he only had 2000 which was his default balance. How can I solve this problem? Thanks.

Upvotes: 2

Views: 214

Answers (2)

Daniel Dearlove
Daniel Dearlove

Reputation: 573

Not directly related to your question but depending on the exact nature of your simulation, representing currency as a double in your simulation may or may not be suitable.

  1. Do you need to be penny-exact?
  2. Do you need to represent fractions of a penny/cent?

Is it important, this is remains perfectly accurate:

for(int count = 0; count < 1000000; ++count)
{
    deposit(acnt, 0.01);   
    display(acnt);
}

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409216

The problem is the loop in both deposit and withdraw functions:

for (auto i: a)

Here i will be a copy of the element in the vector a. All modifications (like calling i.deposit(bl)) will be made on that copy only, not on the element in the vector.

You need to iterate using references to the elements in the vector:

// Note ampersand to make this a reference
//       v
for (auto& i: a)

Upvotes: 5

Related Questions