When it has an "&" it's a pass by reference. That means the changes made to "a" in the function will be permanent. When it doesn't have an "&", the compiler uses a copy of "a" and the changes to "a" in the function aren't permanent in main().
Having a reference returned means that the function can be used on the left hand side of an asignment operator (it is an lvalue). this dose not make sense in your example but constider the following:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class Array {
public:
int size() const;
float& operator[] (int index);
...
};
int main()
{
Array a;
for (int i = 0; i < a.size(); ++i)
a[i] = 7; // This line invokes Array::operator[](int)
...
}
If operator[] did not return a reference, then you could not call Array::operator[](int) in an lvalue position.
Functions can be declared to return a reference type. There are two reasons to make such a declaration:
• The information being returned is a large enough object that returning a reference is more efficient than returning a copy.
• The type of the function must be an l-value.
Just as it can be more efficient to pass large objects to functions by reference, it also can be more efficient to return large objects from functions by reference. Reference-return protocol eliminates the necessity of copying the object to a temporary location prior to returning.
Reference-return types can also be useful when the function must evaluate to an l-value. Most overloaded operators fall into this category, particularly the assignment operator.