4
votes

Question about why is it necessary at all to return a reference from a function.

Following code behaves exactly the same, if we replace int& with int in line9 and line16.

Is it true in my example code, returning reference vs value doesnt matter? In what kind of example it will start to matter?

In my mind, we cant return the reference of a local variable of the function, since the local variable will be out of scope for the caller. Therefore, it only make sense to return a reference of a variable that the caller can see (in scope), but if the caller of the function can see the variable, then it doesnt need to be returned(?) (or is this returning done for the sake of keeping the code neat and tidy?)

Related link: Is returning a reference ever a good idea?

#include <iostream>
using namespace std;

class myClass{
private:
    int val;
public:
    myClass(int);
    int& GetVal();
};

myClass::myClass(int x){
    val = x;
}

int& myClass::GetVal(){
    return val;
}

int main()
{
    myClass myObj(666);
    cout << myObj.GetVal() << endl;
    system("pause");
    return 0;
}
3
The difference can be seen if you assign the result to a reference variable and then modify that variable. There's no difference if you just use the result in an expression.Barmar

3 Answers

6
votes

The difference is that, when you return a reference, you can assign to the result of GetVal():

myObj.GetVal() = 42;

You can also keep the returned reference around, and use it to modify myObj.val later.

If GetVal() were to return val by value, none of this would be possible.

Whether any of this is desirable, or indeed good design, is a different question altogether.

Note that your example is very different to the code in the linked question -- that code returns an invalid reference and is unequivocally a bad idea.

2
votes

In this case the difference is that returning by reference allows caller to modify the data member by assigning value to it, while returning by value returns caller only a copy of the variable.

First allows you to write:

myObj.GetVal() = 100;

While the latter doesn't.

Note that the first in a way allows caller of the function to obtain a reference to a private data member and they can modify it at will. For me this is something which i like to avoid. I do not want users of my class to change the state of my class members at their will.

2
votes

Unless you return a reference code like this will be illegal

int main()
{
    myClass myObj(666);
    myObj.GetVal() = 777;
    return 0;
}

So an important question is whether you want code like that to be legal. In this case I would say not, but other cases may be different.

For your other point you are nearly right, but it's not about whether the user can see the variable, it's about the lifetime of the variable. The user might not be able to see the variable (it might be private for instance) but as long as the variable is still alive then returning a reference to it is not an error.

For complex objects there is also the issue of whether you want to copy the object or return a refernece to the original. That's less likely to be an issue with simple types like int however.