Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why return by reference?

I'm reading through "SAMS Teach Yourself C++ in 21 days" and I came across an example that I can't seem to understand:

#include<iostream>

using namespace std;

class Counter
{
  public:
    Counter() {itsVal=0;}
    const Counter& operator++ ();
    int GetItsVal() {return itsVal;}
  private:
    int itsVal;
};

const Counter& Counter::operator++()
{
  ++itsVal;
  return *this;
}

int main()
{
  Counter i;
  Counter a = ++i;
  cout << "a: " << a.GetItsVal() << " i: " << i.GetItsVal() << endl;
  ++a;
  cout << "a: " << a.GetItsVal() << " i: " << i.GetItsVal() << endl;
}

Why is there an "&" in the declaration of the ++ operator? I understood this to mean that the return type of the ++ operator was a reference, but it doesn't appear to be a reference to i (since incrementing a does not increment i). I've noticed the code returns the same result if I remove both "&", but maybe it's not as efficient.

like image 887
random_forest_fanatic Avatar asked Apr 07 '14 12:04

random_forest_fanatic


People also ask

Why should we return by reference?

Because a reference to the result will be passed out of the function as a reference to the return value, the return value cannot be an automatic variable. in this way, you could use returning reference safely.

When should we return by reference?

A C++ function can return a reference in a similar way as it returns a pointer. When returning a reference, be careful that the object being referred to does not go out of scope. So it is not legal to return a reference to local var. But you can always return a reference on a static variable.

What does return by reference mean?

It means you return by reference, which is, at least in this case, probably not desired. It basically means the returned value is an alias to whatever you returned from the function. Unless it's a persistent object it's illegal.

What happens if you return a reference?

Functions in C++ can return a reference as it's returns a pointer. When function returns a reference it means it returns a implicit pointer.


2 Answers

In C++, when you create a reference, it's a proxy for the original object:

int i = 0;
int& a = i;

++i;
std::cout << i << " " << a << "\n"; // prints '1 1'

++a;
std::cout << i << " " << a << "\n"; // prints '2 2'

Now, in your case:

  • operator++ returns a reference to the current object
  • Counter a = ++i; creates a new object (no & after Counter) initialized as a copy of the reference to i

If you wish a to refer to i, you need to change its declaration:

Counter& a = ++i;
       ^

This will fail to compile thought because the return value of Counter::operator++ is Counter const&: you need to remove the const here which is non-idiomatic for operator++ and thus:

Counter& Counter::operator++() { ++itsVal; return *this; }
like image 161
Matthieu M. Avatar answered Oct 03 '22 21:10

Matthieu M.


Many functions have commonly observed patterns for their return values and general behavior, allowing you to easily and naturally use them.

Pre-increment and Pre-decrement operators always return a reference to the object after performing their task for chaining:

Counter& Counter::operator++()
Counter& Counter::operator--()

While Post-increment and Post-decrement operators either do not return any value, or a temporary containing the old value for easily copied value-types:

Counter Counter::operator++(int)
Counter Counter::operator--(int)

Or

void Counter::operator++(int)
void Counter::operator--(int)

It looks like in your example someone didn't follow common practice.

like image 22
Deduplicator Avatar answered Oct 03 '22 20:10

Deduplicator