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

Discussion in 'C++' started by SB, Feb 22, 2004.

  1. SB

    SB Guest

    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
     
    SB, Feb 22, 2004
    #1
    1. Advertising

  2. SB

    lilburne Guest

    SB wrote:

    > 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.
     
    lilburne, Feb 22, 2004
    #2
    1. Advertising

  3. SB

    David Harmon Guest

    On Sun, 22 Feb 2004 10:42:06 -0500 in comp.lang.c++, "SB"
    <> was alleged to have written:
    > 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.
     
    David Harmon, Feb 22, 2004
    #3
  4. SB

    SB Guest

    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!!!

    "SB" <> wrote in message
    news:g54_b.14306$Dc2.5980@lakeread01...
    > 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
    >
    >
     
    SB, Feb 22, 2004
    #4
  5. * "SB" <> schriebt:
    > [snipped]


    You are ignoring the compiler warnings. Heed the warnings.
     
    Alf P. Steinbach, Feb 22, 2004
    #5
  6. SB

    David Harmon Guest

    On Sun, 22 Feb 2004 16:33:54 GMT in comp.lang.c++, (Alf
    P. Steinbach) was alleged to have written:
    >* "SB" <> schriebt:
    >> [snipped]

    >
    >You are ignoring the compiler warnings. Heed the warnings.


    report4_q3.cpp:27: warning: I'd turn back if I were you.
     
    David Harmon, Feb 22, 2004
    #6
  7. "SB" <> wrote in message
    news:cA4_b.14314$Dc2.5864@lakeread01...
    > Thanks, I'm still a little unsure why my original way didn't work


    > > double getBalance();

    This does not return a reference to your internal member. It returns
    a copy of the value of that member.

    > > a.deposit(a.getBalance(), amount);

    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
     
    Thomas Wintschel, Feb 22, 2004
    #7
  8. SB

    torhu Guest

    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.
     
    torhu, Feb 22, 2004
    #8
  9. "SB" <> wrote in message news:<g54_b.14306$Dc2.5980@lakeread01>...
    > 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.
     
    Chris Mantoulidis, Feb 22, 2004
    #9
  10. SB

    Guest

    "SB" <> wrote in message news:<g54_b.14306$Dc2.5980@lakeread01>...
    [snippers]
    > 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
     
    , Feb 23, 2004
    #10
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. malik

    Believe iT or NOT!!!

    malik, Feb 19, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    366
    malik
    Feb 19, 2004
  2. chas
    Replies:
    3
    Views:
    362
    Roedy Green
    Nov 18, 2003
  3. Giorgio Franceschetti

    Cannot believe this. Problems with double and float

    Giorgio Franceschetti, Jan 16, 2004, in forum: Java
    Replies:
    3
    Views:
    436
    Giorgio Franceschetti
    Jan 19, 2004
  4. Dwayne
    Replies:
    8
    Views:
    425
    nice.guy.nige
    Feb 28, 2004
  5. David Oriol

    I can't believe it

    David Oriol, Nov 28, 2009, in forum: C Programming
    Replies:
    0
    Views:
    277
    David Oriol
    Nov 28, 2009
Loading...

Share This Page