Home > front end >  Is there a way to modify another object's member directly from within one object's functio
Is there a way to modify another object's member directly from within one object's functio

Time:03-01

all! This is my first post, so please be gentle.

My code is meant to simulate a rudimentary version of transferring money from one bank account to another. My code is as follows:

#include <cstdio>

struct Account
{
    virtual ~Account() {}
    virtual double get_balance() = 0;
    virtual double set_balance(double amount) = 0;
    virtual Account* transfer_balance(Account* to, double amount) = 0;

    long account_id;
    double balance;
    unsigned int privileges;
};

struct UserAccount : Account
{
    UserAccount(long account_id): account_id{account_id} {
        printf("Account %ld initialized at %p\n", account_id, this);
    };

    double get_balance() override
    {
        return balance;
    }
    double set_balance(double amount) override
    {
        this->balance = amount;
        return balance;
    }
    Account* transfer_balance(Account* to, double amount) override
    {
        to->set_balance(to->get_balance()   amount);
        this->set_balance(this->get_balance() - amount);
        return to;
    }

    long account_id;
    double balance
    { 0 };
    unsigned int privileges;
};

int main()
{
    UserAccount test_acct_one(23);
    UserAccount test_acct_two(98);
    
    test_acct_one.transfer_balance(&test_acct_two, 200);

    printf("Balance of Account %ld: %lG\n", test_acct_one.account_id, test_acct_one.get_balance());
    printf("Balance of Account %ld: %lG\n", test_acct_two.account_id, test_acct_two.get_balance());
}

Output:

Account 23 initialized at 0x7fff8e927a40
Account 98 initialized at 0x7fff8e927a00
Balance of Account 23: -200
Balance of Account 98: 200

While this code works, it feels a bit finicky to transfer the values like this:

to->set_balance(to->get_balance()   amount);
this->set_balance(this->get_balance() - amount);

However, when I try to do this:

to->balance  = amount;
balance -= amount;

The output turns into:

Account 23 initialized at 0x7ffc37b91a40
Account 98 initialized at 0x7ffc37b91a00
Balance of Account 23: -200
Balance of Account 98: 0

As you can see, while Account 23's (the first one's) balance is properly set to -200, Account 98's (the second one's) balance neither increases nor decreases, and I can't understand why. Some explanation of this behavior would be much appreciated.

CodePudding user response:

You've duplicated all your member variables in both types. When you attempt to modify balance directly, it's trying to modify Account::balance, but set_balance and get_balance will use UserAccount::balance since that's available in the scope where the virtual is implemented.

CodePudding user response:

Your UserAccount class has a balance member and is derived from the Account class which also has a balance member. When you access the balance through the virtual functions in Account, it changes UserAccount::balance. But when you increment the member variable directly with to->balance = amount, it's Account::balance which is used because to is a pointer to Account.

Decide whether you really need to user virtual functions. (I don't see that you do.) If you keep them, remove the variables from Account and access the balance through virtual functions. If you decide to remove the virtual functions, you really only need one class so it's pretty obvious which number you're incrementing.

struct UserAccount
{
    UserAccount(long account_id): account_id{account_id} {
        printf("Account %ld initialized at %p\n", account_id, this);
    };

    double get_balance()
    {
        return balance;
    }
    double set_balance(double amount)
    {
        this->balance = amount;
        return balance;
    }
    UserAccount* transfer_balance(UserAccount* to, double amount)
    {
        to->balance  = amount;
        balance -= amount;
        return to;
    }

    long account_id;
    double balance
    { 0 };
    unsigned int privileges;
};
  •  Tags:  
  • c
  • Related