Say I have the following code:
#include <iostream>
using namespace std;
class Account
{
private:
float balance;
public:
Account() { balance = 0.0; };
float GetBalance() { return balance; };
void SetBalance(float newBalance) { balance = newBalance; };
};
Account mainAccount;
Account& GetAccount()
{
return mainAccount;
}
void PrintAccountInfo()
{
cout << "mainAccount's balance is " << mainAccount.GetBalance() << endl;
}
int main()
{
PrintAccountInfo();
Account &a = GetAccount(); // Line 31
a.SetBalance(30.0);
PrintAccountInfo();
return 0;
}
When I run it, I get the following output (as expected):
mainAccount's balance is 0
mainAccount's balance is 30
However, on line 31, if I take out the "&" in the "Account &a", to make it this:
Account a = GetAccount(); // note lack of "&"
I get this output:
mainAccount's balance is 0
mainAccount's balance is 0
How come? I thought when returning a reference, the "&" is redundant / not necessary? Am I fundamentally misunderstanding how references work in C++?
EDIT: Thanks, I understand now why the two are different. However, then shouldn’t I be able to do this:
Account GetAccount()
{
return mainAccount;
}
int main()
{
Account &a = GetAccount();
// ....
}
However, when I run that, I get an error:
untitled: In function ‘int main()’:
untitled:31: error: invalid initialization of non-const reference of type ‘Account&’ from a temporary of type ‘Account’
You thought wrong.
Consider these two different lines:
In the first, you declare a reference called
awhich is bound to the object returned by the functionGetAccount.In the second, you declare an object
awhich is copy-initialized by the object returned by the functionGetAccount.Fundamentally: one declares a reference, the other declares an object.
EDIT: Answering the follow-on question:
You certainly can remove the
&, but then your behavior will change. Consider these two functions:In the first, you return a temporary object which has been copy-initialized from the
mainAccountobject. In the second you return a reference to themainAccountobject.If you want
ato be a reference tomainAccount, you need&in both places.If you want
ato be a copy ofmainAccount, you need no&in the declaration ofa. The other declaration won’t matter in this case.If you want
ato be a reference to a compiler-generated temporary value (hint: you don’t), declareawith&, butGetAccountwithout.