Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: what is the advantage of references in this case?

I have two pieces of code:

int f1(int b)
{
   return b;
}

int & f2(int b)
{
   return b;
}

What is the difference between these functions? I know that the second one returns a reference, but since I can use both functions in the same way, what's the difference?

Edit: Is this function better?

int && f2(int b)
{
   return b;
}

And when should I use functions which return references?

Edit2: Then when should I use functions which return Rvalue references?

like image 581
user2738748 Avatar asked Dec 05 '22 20:12

user2738748


2 Answers

Consider a simple class that wraps an array solely for the purpose of providing an example of what the OP can do with a returned reference.

class example
{
private:
    int array[]= {1,2,3,4,5,6,7,8,9,0};
public:
    int get(int index)
    {
        return array[index];
    }
    int & get2(int index)
    {
        return array[index];
    }
}

Now we have an example that will not go into the badlands of undefined behaviour and can show you the power of this fully armed and operational reference.

Say we have

example x;

We can call either get function to retrieve a value

int val1 = x.get(1);
int val2 = x.get2(2)

but we can also

x.get2(3) = 30;

because get2 returns a reference we can assign to it and make the assignment stick.

This is invaluable should you want to add an index operator to example

int & operator[](int index)
{
    return array[index];
}

because it allows the expected array behaviour

int val = x[5];
x[6] = 10;

EDIT

Tony D brings up another important feature. Returning a reference returns by reference. In addition to allowing modification of the returned object, this does not make a copy and saves whatever effort would have been consumed by making a copy. For the example case of integers this is moot. The cost of passing an integer and a reference to an integer will either be the same or so close that it shouldn't matter. This is not true of a larger, more complex object that could take a significant amount of effort to copy or an object that cannot or should not be copied.

BigFreakingObject & getBigFreakingObject();

will allow the caller to operate on a BigFreakingObject without incurring the costs of duplicating it. This hands over the keys to the kingdom however and allows the caller to do to BigFreakingObject whatever BigFreakingObject's permissions will allow, and this may conflict with the requirements of BigFreakingObject's owner.

Declaring the reference as const with

const BigFreakingObject & getBigFreakingObject();

or

BigFreakingObject const & getBigFreakingObject();

will provide a reference to a BigFreakingObject but not allow the caller to modify its state, protecting the owner of BigFreakingObject from any unpleasant surprises.

For more details on this, read up on Const Correctness.

like image 68
user4581301 Avatar answered Dec 21 '22 09:12

user4581301


int f1(int b) {
   return b;
}

returns the integer b.

int & f2(int b) {
   return b;
}

returns a reference to an integer b that was destroyed when the function returned. In other words, you passed b by value to the function, which means b has an address in the stack frame of the function. Once the function returns, anything in that function's stack frame, including the b that you returned a reference to, no longer exists. So, you have no idea what the reference actually refers to, so you can't use it.

Edit: Your edited function is not better. This would be more correct:

int& f2(int& b) {
   return b;
}

Unless you have a situation like the example @user4581301 gave, you should never return a reference to an object created within the function you are returning from, for the reasons described above!

If you want to pass an object to a function, and have the function do something to that object without ever making a copy of the object, do the following:

void f2(int& b) {
    ... do stuff to b
}
like image 35
Alexander Bolinsky Avatar answered Dec 21 '22 11:12

Alexander Bolinsky