When returning an object reference from C ++, is it necessary to use the "&" operator in the returned variable?

Let's 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 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 balance is 0 mainAccount balance is 30 

However, on line 31, if I select "&" in "Account & a" to do it like this:

 Account a = GetAccount(); // note lack of "&" 

I get this output:

 mainAccount balance is 0 mainAccount balance is 0 

How did it happen? I thought returning the link, "&" is redundant / optional? I basically misunderstand how links work in C ++?

EDIT: Thanks, now I understand why they are different. However, then I should not do this:

 Account GetAccount() { return mainAccount; } int main() { Account &a = GetAccount(); // .... } 

However, when I run this, I get an error:

untitled: In the function 'int main ():

untitled: 31: error: invalid initialization of a non-constant link of type 'Account & from the temporary type' Account

+4
source share
5 answers

I thought returning the link, "&" is redundant / optional?

You were wrong.

Consider these two different lines:

 Account &a = GetAccount(); // Line 31 Account a = GetAccount(); // Line 31 

In the first, you declare a link called a , which is bound to the object returned by the GetAccount function.

In the second, you declare an object a , which is initialized with a copy of the object returned by the GetAccount function.

Essentially: one declares a link, the other declares an object.


EDIT : Answering the following question:

"you can remove & from the return type in the declaration of the GetAccount function: Account GetAccount() { return mainAccount; } "

You can of course remove & , but then your behavior will change. Consider these two functions:

 Account GetAccount() { return mainAccount; } Account &GetAccount() { return mainAccount; } 

In the first case, you return a temporary object that was initialized with a copy from the mainAccount object. In the second, you will return a reference to the mainAccount object.

  • If you want a to be a reference to mainAccount , you need & in both places.

  • If you want a to be a copy of mainAccount , you do not need & in the declaration of a . In this case, another declaration does not matter.

  • If you want a to be a reference to a temporary value generated by the compiler (hint: you won't), declare a with & , but GetAccount without.

+3
source

You return the link, but then create a new object using this link. a is a new object that is initialized using the link returned from GetAccount .

Remember that the link is an alias. This is how to say:

 int x = 0; int& y = x; int z = y; //is equivalent to z = x; 

z does not apply to x and y in this case, because z itself is not a reference.

So:

 x = 1; 

will change both x and y , but z will still be 0.

+2
source

In both cases, you return the link, but there is a difference in how you use it:

 Account &a = GetAccount(); 

In this case, you use the link to initialize another link, making a link to the source data.

 Account a = GetAccount(); 

In this case, you use the returned link to initialize an object of type Account instead of the link to the Account. Therefore, you copy the source object to the newly created a .

+2
source

It matters.

This version

 Account a = GetAccount(); // note lack of "&" 

creates a copy of the account, not a link. Therefore, when changing the balance, you change the balance of the copy, not the original.

0
source

To answer a question from the name: Not directly.

 typedef Account& AccountRef; // Hiding here AccountRef GetAccount() { return mainAccount; } 

BTW, & not used here. It changes the type of Account . It can be used as a unary and binary operator, for example. in &obj or 5 & 6 . When used as an operator, it must appear before or between expressions.

0
source

Source: https://habr.com/ru/post/1432810/


All Articles