# Thread: Returning a reference? Why?

1. ## Returning a reference? Why?

Taken from cplusplus.com tutorial:

Code:
```CVector& CVector::operator= (const CVector& param)
{
x=param.x;
y=param.y;
return *this;
}```
My question is: why do we return a CVector& and not just CVector? Could someone please explain it to me in detail?

2. Consider what happens in operator chaining:
Code:
`a = b = c;`
If the copy assignment operator returns a copy, then (b = c) would generate a copy which would then be assigned to a, resulting in a total of three copies. This is unnecessary work. By returning a (const) reference, on the other hand, only two copies are made.

3. Code:
`a = b = c;`
This may sound silly, but is this equivalent to:

Code:
```b = c;
a = b;```
Or:

Code:
```b = c;
a = c;```
If it's the latter, then what you say makes sense. If it's the former, then I'm still a little bit puzzled.

4. Originally Posted by Mr_Miguel
Code:
`a = b = c;`
This may sound silly, but is this equivalent to:
Code:
```a = b = c;  // is equivalent to
a = (b = c); // is equivalent to (functionally, at least):
b = c;
a = b;```
This is most useful in statements such as:
Code:
`a = b = c = d = 0;`
--
Mats

5. Well then... Let's assume that's true. Let's also assume for a moment that the operator = returns CVector. Then:

Code:
```CVector c;
b = c; //b is now a copy of CVector c;
a = b; //a is now a copy of CVector b;

//We now have three copies: one at c, one at b, one at a.```
Right? Now let's go back to reality. It returns a CVector&. Then:

Code:
```CVector c;
b = c; //b is now a copy of CVector c;
a = b; //a is now a copy of CVector c;```
Is that what it means? That, when returning a reference, a becomes the same copy as b?

6. Originally Posted by Mr_Miguel
Well then... Let's assume that's true. Let's also assume for a moment that the operator = returns CVector. Then:

Code:
```CVector c;
b = c; //b is now a copy of CVector c;
a = b; //a is now a copy of CVector b;

//We now have three copies: one at c, one at b, one at a.```
Right? Now let's go back to reality. It returns a CVector&. Then:

Code:
```CVector c;
b = c; //b is now a copy of CVector c;
a = b; //a is now a copy of CVector c;```
Is that what it means? That, when returning a reference, a becomes the same copy as b?
No, they are distinct copies. The operator= makes sure of that. It's just that if you have

Code:
`CVector CVector::operator= (const CVector& param) ....`
then you also get the compiler to copy the *this when it is returned back to the calling code. Which is a bit unnecessary, as we are not going to modify the return value.

--
Mats

7. Well then... Let's assume that's true. Let's also assume for a moment that the operator = returns CVector. Then:

Code:

CVector c;
b = c; //b is now a copy of CVector c;
a = b; //a is now a copy of CVector b;

//We now have three copies: one at c, one at b, one at a.
If you do a = b = c and operator= returns a copy, you should get
a) c is copied to b: assignment
b) b is copied to pass to operator= of instant a: copy constructor
c) copy of b is copied to a
d) a is copied and returned but not used: copy constructor

In code
Code:
```     CVector a, b, c;
b = c;
a = CVector(b);
CVector(a);```
If you return a reference, calls to copy constructors won't happen.

Hence, if you can return large objects as references (if the returned object is not local to the function), do so.

8. First lets make sure we're all on the same page...
Code:
```CVector& CVector::operator= (const CVector& param)
{
x=param.x;
y=param.y;
return *this;
}```
When you do: a = b; then b = param in the function above, and a = this.
For a simple statement like that, you don't care about the return value since you're not assigning a to anything else; but in the following case:
a = b = c;
c = param & b = this, then the reference that is returned is sent to operator=() again, but this time the previous return value = param, and a = this.

There's no point in creating a whole new object and returning it because in the first case nobody will use it anyways, and in the second case a reference will do just as well as a new object, but without the extra work required to create an object...

9. From http://www.codeproject.com/useritems...ces_in_c__.asp

References are nothing but constant pointer in C++. A Statement int &i = j; will be converted by compiler to int *const i = &j; i.e References are nothing but constant pointers. They need initialization because constants must be initialized and since the pointer is constant they can't point to anything else. Lets take the same example of references in C++ and this time we will use the syntax what compiler uses when it sees references.
That explains it. If a reference is just a constant pointer, then I understand why you say it's better to return a reference: pointers have tipically the size of 4 bytes (at least in 32-bit machines); objects themselves can be much larger than 4 bytes. Am I right?

10. Originally Posted by Mr_Miguel
From http://www.codeproject.com/useritems...ces_in_c__.asp

That explains it. If a reference is just a constant pointer, then I understand why you say it's better to return a reference: pointers have tipically the size of 4 bytes (at least in 32-bit machines); objects themselves can be much larger than 4 bytes. Am I right?
Yup, that's the point - references are smaller than most objects.

--
Mats

11. References are nothing but constant pointer in C++. A Statement int &i = j; will be converted by compiler to int *const i = &j; i.e References are nothing but constant pointers.
In practice I believe this is true, but conceptually references are a little more than constant pointers. They are aliases of existing objects, and as such there are no null references, even though there can be null constant pointers.

If a reference is just a constant pointer, then I understand why you say it's better to return a reference: pointers have tipically the size of 4 bytes (at least in 32-bit machines); objects themselves can be much larger than 4 bytes. Am I right?
Yes.

12. http://www.parashift.com/c++-faq-lit...s.html#faq-8.1

It seems a reference is implemented using the machine address of an object. A pointer also contains the address of an object, but it seems a reference isn't quite a pointer itself.

Anyways, point taken. Thank you all for your help.

13. Originally Posted by Mr_Miguel
http://www.parashift.com/c++-faq-lit...s.html#faq-8.1

It seems a reference is implemented using the machine address of an object. A pointer also contains the address of an object, but it seems a reference isn't quite a pointer itself.

Anyways, point taken. Thank you all for your help.
There is a difference in the MEANING (semantics) of a reference and a pointer [not to mention that the way you "access" a pointer vs. a reference is different], but the internal implementation is a pointer [at least in most architectures]. However, the fact that it's a pointer is "hidden" from the programmer in all aspects - the programmer just "knows" that it is "the same object as somewhere else".

And the benefit of returning a reference vs. a copy of the object, the benefit is that a reference is the same size as a pointer, so the returned value is "short" relative to the whole object, and that is why it's used here.

--
Mats