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;
};