I can't believe I'm having this problem...PLEASE HELP!

S

SB

Ok, very simple problem. I'm trying to update a value by calling a function
using pass by reference, but it does not update the value. In short, the
value I'm trying to update is balance, which is a private member of the
class Account. I have a public function called getBalance(). I have another
public function called deposit, which I pass the balance (by calling
getBalance() using pass by reference) and a second value for the amount of
deposit. Inside the deposit() function if I print the value of the balance
plus the amount to be deposited, it prints the right value, i.e. current
balance plus deposit amount. However, it's not updating the balance member
of the Account class because when I call the getBalance(), it still shows
the original value before the deposit. I know I'm missing something very
simple here, but I just can't see it. Also, I'm getting the following
warning regarding the function calls using pass by reference, but I don't
understand it..

report4_q3.cpp: In function `int main()':
report4_q3.cpp:20: warning: initialization of non-const reference `double &'
from rvalue `double'
report4_q3a.cpp:21: warning: in passing argument 1 of
`Account::deposit(double &, double)'
report4_q3.cpp:27: warning: initialization of non-const reference `double &'
from rvalue `double'
report4_q3a.cpp:29: warning: in passing argument 1 of
`Account::withdrawal(double &, double)'


Here's the .h file....(report4_q3.h)
using namespace std;

class Account
{
private:
double balance;

public:
Account(); // default constructor
double getBalance();
void setBalance(double);
void deposit(double&, double);
void withdrawal(double&, double);
~Account(); // destructor
};

Here's the implementation file...(report4_q3a.cpp)
#include <iostream>
#include <string>

#include "report4_q3.h"

using namespace std;

// default constructor
Account::Account()
{
// give a starting balance of $500
balance = 500.00;
}

double Account::getBalance()
{
return balance;
}

void Account::deposit(double& bal, double deposit)
{
cout<<endl<<"making a deposit!"<<endl;
bal += deposit;
cout<<"after transaction balance is: $"<<bal<<endl; //this of course shows
the correct balance
}

void Account::withdrawal(double& bal, double withdrawal)
{
cout<<"making a withdrawal!"<<endl;
bal -= withdrawal;
cout<<"Your new balance is $"<<getBalance()<<endl;
}

// destructor
Account::~Account()
{
// do nothing
}

Here's the file with main...(report4_q3.cpp)
#include "report4_q3a.cpp"

using namespace std;

int main()
{
Account a;
int inputVal = 0;
double amount = 0.0;

cout<<"Your balance is: $"<<a.getBalance()<<endl;
cout<<endl<<"Press 1 to make a deposit, Press 2 to make a withdrawal, 3 for
account balance and 4 to quit."<<endl;
cin>>inputVal;

switch(inputVal)
{
case 1: {
cout<<"Enter the amount to deposit: ";
cin>>amount;
a.deposit(a.getBalance(), amount);
cout<<"Your new balance is $"<<a.getBalance()<<endl; // right here it
shows the original balance which is incorrect
}
break;
case 2: {
cout<<"Enter the amount to withdrawal: ";
cin>>amount;
a.withdrawal(a.getBalance(), amount);
}
break;
case 3: cout<<"Your balance is: $"<<a.getBalance()<<endl;
break;
case 4: return 0;
break;
default: cout<<"You have entered an invalid value - try again."<<endl;
}

return 0;
}

Any help is GREATLY appreciated!
Thanks!
SB
 
L

lilburne

SB said:
Ok, very simple problem. I'm trying to update a value by calling a function
using pass by reference, but it does not update the value. In short, the
value I'm trying to update is balance, which is a private member of the
class Account. I have a public function called getBalance(). I have another
public function called deposit, which I pass the balance (by calling
getBalance() using pass by reference) and a second value for the amount of
deposit. Inside the deposit() function if I print the value of the balance
plus the amount to be deposited, it prints the right value, i.e. current
balance plus deposit amount. However, it's not updating the balance member
of the Account class because when I call the getBalance(), it still shows
the original value before the deposit. I know I'm missing something very
simple here, but I just can't see it. Also, I'm getting the following
warning regarding the function calls using pass by reference, but I don't
understand it..

You are returning a double and then passing as a non-const
reference, you can't do that in C++. Besides the expression
bal -= withdrawal for example won't actually do anything
because it affects the temporary.
 
D

David Harmon

I have a public function called getBalance(). I have another
public function called deposit, which I pass the balance (by calling
getBalance() using pass by reference)

Don't attempt to pass the balance as an argument to deposit().
Have deposit() update the member variable directly.

What you are doing is like: the ATM machine prints out a piece of paper
with your balance on it (getBalance) and to make a deposit you cross out
the amount on the paper and write in a new amount. The next time the
ATM prints a receipt, mysteriously the old amount is still there. This
is what all the messages about temporary (copy of the balance) bound to
non-const reference are telling you.
 
S

SB

Thanks, I'm still a little unsure why my original way didn't work...I'll
have to read your explaination again to fully understand. However, I did
what one of you suggested and just wrote a setBalance function which
directly updated the balance member directly, which worked perfectly.

Thanks!!!
 
T

Thomas Wintschel

SB said:
Thanks, I'm still a little unsure why my original way didn't work
This does not return a reference to your internal member. It returns
a copy of the value of that member.
When you make this call, you are passing a reference to the temporary
object returned by getBalance, not to your internal member.

In any case, there is no reason to pass a reference to something the
object already has access to.

Tom
 
T

torhu

Hello!

References in C++ can certainly be a bit confusing!

Look at this:
void deposit(double&, double);

and this:
double getBalance();

The problem is that the value getBalance() returns is only a copy of
a.balance. This means that the value deposit() changes is only a
temporary variable that disappears whan deposit() exits. This is what
the compiler tries to warn you about, that you possibly don't mean
what you say!

Do this instead:
double& getBalance();

Now, getBalance() returns a reference (the address of the the
variable, instead of the value) to a.balance. Now deposit() will
change a.balance directly, not just a copy.
 
C

Chris Mantoulidis

SB said:
Ok, very simple problem. I'm trying to update a value by calling a function
using pass by reference, but it does not update the value. In short, the
value I'm trying to update is balance, which is a private member of the
class Account. I have a public function called getBalance(). I have another
public function called deposit, which I pass the balance (by calling
getBalance() using pass by reference) and a second value for the amount of
deposit. Inside the deposit() function if I print the value of the balance
plus the amount to be deposited, it prints the right value, i.e. current
balance plus deposit amount. However, it's not updating the balance member
of the Account class because when I call the getBalance(), it still shows
the original value before the deposit. I know I'm missing something very
simple here, but I just can't see it. Also, I'm getting the following
warning regarding the function calls using pass by reference, but I don't
understand it..

report4_q3.cpp: In function `int main()':
report4_q3.cpp:20: warning: initialization of non-const reference `double &'
from rvalue `double'
report4_q3a.cpp:21: warning: in passing argument 1 of
`Account::deposit(double &, double)'
report4_q3.cpp:27: warning: initialization of non-const reference `double &'
from rvalue `double'
report4_q3a.cpp:29: warning: in passing argument 1 of
`Account::withdrawal(double &, double)'


Here's the .h file....(report4_q3.h)
using namespace std;

class Account
{
private:
double balance;

public:
Account(); // default constructor
double getBalance();
void setBalance(double);
void deposit(double&, double);
void withdrawal(double&, double);
~Account(); // destructor
};

Here's the implementation file...(report4_q3a.cpp)
#include <iostream>
#include <string>

#include "report4_q3.h"

using namespace std;

// default constructor
Account::Account()
{
// give a starting balance of $500
balance = 500.00;
}

double Account::getBalance()
{
return balance;
}

void Account::deposit(double& bal, double deposit)
{
cout<<endl<<"making a deposit!"<<endl;
bal += deposit;
cout<<"after transaction balance is: $"<<bal<<endl; //this of course shows
the correct balance
}

void Account::withdrawal(double& bal, double withdrawal)
{
cout<<"making a withdrawal!"<<endl;
bal -= withdrawal;
cout<<"Your new balance is $"<<getBalance()<<endl;
}

// destructor
Account::~Account()
{
// do nothing
}

Here's the file with main...(report4_q3.cpp)
#include "report4_q3a.cpp"

using namespace std;

int main()
{
Account a;
int inputVal = 0;
double amount = 0.0;

cout<<"Your balance is: $"<<a.getBalance()<<endl;
cout<<endl<<"Press 1 to make a deposit, Press 2 to make a withdrawal, 3 for
account balance and 4 to quit."<<endl;
cin>>inputVal;

switch(inputVal)
{
case 1: {
cout<<"Enter the amount to deposit: ";
cin>>amount;
a.deposit(a.getBalance(), amount);
^^^^^^^^^^^^^^
this returns a double, not a double &. That means you can't edit it
(i.e. you can't say a.getBalance() = 10.5;). But the 1st parameter in
deposit is expected to be a double & so that it can be changed. That's
what's causing you your problem. Change the return type of
Account::getBalance() from double to double &.
cout<<"Your new balance is $"<<a.getBalance()<<endl; // right here it
shows the original balance which is incorrect
}
break;
case 2: {
cout<<"Enter the amount to withdrawal: ";
cin>>amount;
a.withdrawal(a.getBalance(), amount);
}
break;
case 3: cout<<"Your balance is: $"<<a.getBalance()<<endl;
break;
case 4: return 0;
break;
default: cout<<"You have entered an invalid value - try again."<<endl;
}

return 0;
}

Any help is GREATLY appreciated!
Thanks!
SB

First of all, in deposit and withdraw, why do you need the 1st
parameter? Just use those 2 functions for the current object. No need
for the first param. That IS what's causing you your problem. See
above.
 
P

puppet_sock

SB said:
class Account
{
private:
double balance;

public:
Account(); // default constructor
double getBalance();
void setBalance(double);
void deposit(double&, double);
void withdrawal(double&, double);
~Account(); // destructor
}; [snip]
void Account::deposit(double& bal, double deposit)
{
cout<<endl<<"making a deposit!"<<endl;
bal += deposit;
cout<<"after transaction balance is: $"<<bal<<endl; //this of course shows
the correct balance
}

Ok, it's not entirely clear what you want to do here.
But it looks like this should be like so:

The prototype inside the .h file should be:

void deposit(double);


And the code should be:

void Account::deposit(double deposit)
{
balance += deposit;
}

That is, you should be working directly on the data member, and
not exposing it to the outside world.

This is an excuse for me to get on one of my hobby horses about
object orientation. Try not to think of an object as just a
container of data and functions. Try to think of it as an
exporter of services. Sometimes the services it exports are
little more than just holding data. But here, it looks like
you are working on some kind of bank account thing. Well, to
deposit money into an account you don't need to know how much
money is already in there. (Well, usually anyway.) You just
shove it in there. And also, to finish a deposit, you don't
need to know other details, like how much is in there after
the deposit, where the bank stores the money, etc.

So, think of Account objects as things that have a place you
can shove money in (the deposit function). Then you can see
that there are plenty of other changes you will want to make.
For example, you should be checking for negative amounts,
and doing something about it when they happen. You might
try returning the actual amount deposited.

Also, an Account is a thing you can pull money out of. Again,
you should think about how that actually works. You request
an amount. You get some amount back. As long as you get
what you asked for, you don't need to know the balance
before or after. And since you've got other functions for
that, you don't need that in your withdrawal function.
All you want is to have the function return the actual
amount you withdrew.
Socks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top