mathematted mathematted - 3 months ago 8
C++ Question

Data from a static vector left unchanged when I leave the method

This is a Bank project I had in mind while learning C++ and I
have been adding to it as I learned inheritance and pointers. The
user is a bank teller who can create a new customer or process
transactions of an existing customer.

A

Customer
has
Savings
and
Checking
classes as private fields that inherit
from
Account
. The
Bank
class adds/gets customers from its private
static vector<Customer>
field.

The unexpected result is that in the 'process_transaction' method I can fetch
a customer from vector and deposit/withdrawl from it's accounts, but once I leave the method and come back to it the accounts data hasn't changed from the time I initialized them.

Need help. It's a reference to customer issue? When should I return by
reference or pointer?

Here is the code. In the driver class I have a method to create a customer

/*
* Create customer from teller input then add the Customer
* to Bank's private static vector<Customer> field.
*/
int create_customer(){
cout << "** Create New Customer **\n";
cout << "Customer Name: ";
string n = "";
cin >> n;
Customer* d = new Customer(n, gen_acct_number());
Customer c(*d);
// get opening balances
double open_ck = 0;
double open_sv = 0;
cout << "Opening Balance For Checking: ";
cin >> open_ck;

cout << "Opening Balance For Savings: ";
cin >> open_sv;
cout << "\n";

// create and set accounts
Checking ck(open_ck);
Savings sv(open_sv);
c.set_checking(ck);
c.set_savings(sv);

// add customer to bank
Bank b;
b.add_customer(c);
cout << "New Customer: " << c.get_name() << endl;
cout << "Account Number: " << c.get_acct_number() << endl;
cout << "\n";
return 0;

}


I have another method in the driver class to process a customer. Once I
leave this method a customer's accounts are unchanged, but works otherwise.

/*
* Fetch customer by account number from Bank's private static
* vector<Customer> and perform transactions on Customer's accounts
* until teller has finished processing the customer.
*/
int process_customer(){
cout << "** Process Transaction **\n";
cout << "Account Number: ";
int acctNum = 0;
cin >> acctNum;
cout << "\n";

// get customer
Bank b;
Customer c = b.get_customer(acctNum);

//if(c* == NULL){
// cout << "Error: Customer Not Found.\n";
// return 0;
//}

bool flag = true;
while(flag){
cout << c.get_name() << " #" << c.get_acct_number() << ": ";

cout << "Select a transaction.\n";
cout << "1. Withdrawl\n";
cout << "2. Deposit\n";
cout << "3. Check Balance\n";
cout << "4. Quit\n";
cout << "> ";
int choice = 0;
cin >> choice;
cout << "\n";

double amt = 0;
int which = 0;
switch(choice){
case 1:{ // WITHDRAWL

cout << "Withdrawl From: \n";
cout << "1. Checking \n2. Savings \n";
cout << "> ";
cin >> which;
cout << "\n";
cout << "Amount: ";
cin >> amt;
cout << "\n";

if(which == 1){
cout << "Old Balance: " << c.get_checking().get_balance() << endl;
c.get_checking().withdrawl(amt);
cout << "New Balance: " << c.get_checking().get_balance() << endl;
cout << "\n";
}else if (which == 2){
cout << "Old Balance: " << c.get_savings().get_balance() << endl;
c.get_savings().withdrawl(amt);
cout << "New Balance: " << c.get_savings().get_balance() << endl;
cout << "\n";
}else{
break;
}
break;
}
case 2:{ // DEPOSIT

cout << "Deposit Into: \n";
cout << "1. Checking \n2. Savings \n";
cout << "> ";
cin >> which;
cout << "\n";

cout << "Amount: ";
cin >> amt;
cout << "\n";
if(which == 1){
cout << "Old Balance: " << c.get_checking().get_balance() << endl;
c.get_checking().deposit(amt);
cout << "New Balance: " << c.get_checking().get_balance() << endl;
cout << "\n";

}else if (which == 2){
cout << "Old Balance: " << c.get_savings().get_balance() << endl;
c.get_savings().deposit(amt);
cout << "New Balance: " << c.get_savings().get_balance() << endl;
cout << "\n";
}else{
break;
}
break;
}
case 3:{ // CHECK BALANCE

cout << "Checking " << c.get_checking().get_balance() << endl;
cout << "Savings " << c.get_savings().get_balance() << endl;
cout << "\n";
break;
}
default:{ // EXIT

flag = false;
break;
}
}
}

return 0;
}


The Bank class.

Bank::Bank(){}

Customer& Bank::get_customer(int acct_number) {

for(unsigned i = 0; i < cus.size(); i++){
if(cus[i].get_acct_number() == acct_number){
return cus[i];
}
}
return cus[0];
}
void Bank::add_customer(Customer c){
cus.push_back(c);
}

/* Disabled. I want to pass an account to these methods.
*
* void Bank::deposit(double amt, Account& a){
* a.deposit(amt);
* }
* void Bank::withdrawl(double amt, Account& a){
* a.withdrawl(amt);
* }
* double Bank::check_balance( Account& a){
* return a.get_balance();
* }
*/


vector<Customer> Bank::cus;


Bank.h


#ifndef BANK_H_
#define BANK_H_


#include "../include/Customer.h"
#include <string>
#include <vector>
using namespace std;

class Bank{

public:
Bank();
Customer& get_customer(int acct_number);
void add_customer(Customer c);
void deposit(double amt, Account& a);
void withdrawl(double amt, Account& a);
double check_balance( Account& a);
private:
static vector<Customer> cus;
};



#endif /* BANK_H_ */

Answer

It does indeed appear to be a reference issue. In your process_customer function, change:

// get customer
Bank b;
Customer c = b.get_customer(acctNum);

to:

// get customer
Bank b;
Customer& c = b.get_customer(acctNum);

Without this change, you're making a copy of the customer and then modify this copy, instead of modifying the original customer.

Comments