The &
prefix on the identifier being declared makes it a reference. Because the reference isn't const, the argument expression has to be an lvalue (i.e. has to designate an object). The function can modify that object!
If the function doesn't modify the object and you don't try to pass something which isn't an object, such as a null pointer constant, you won't notice any difference.
The declared type doesn't change; either way, the type is node *
. A reference isn't a type; it's an aspect of how a name refers to a value.
For instance if we have:
int x = 0, y = 2;
there are two objects. If we declare y
as a reference, there is one object of type int
, which effectively has two names:
int x = 0, &y = x;
the initializer for the reference is the x
object itself, rather than x
's value.
When we declare a function parameter as a reference, it becomes a "reference parameter". The way the function receives the value through that parameter changes from the usual "pass by value" semantics inherited from C.
It's also possible to bind references to const
types. Const reference parameters are curious; they can receive literal objects as values:
void foo(const int &x); // can be called as foo(42); !
Const references are useful because when you pass a const reference to a class object, it resembles "pass by value", but is cheaper because the object itself is passed (no copy construction takes place).
Const references were introduced into C++ to solve the problem of "what should the parameter of a copy constructor be?". A copy constructor cannot look like this:
some_class::some_class(some_class original_obj) { /*...*. }
because this creates a chicken-and-egg problem: passing the object to the copy constructor requires a copy (due to the by-value semantics) which requires a copy constructor! Const reference invention to the rescue:
some_class::some_class(some_class &original_obj) { /*...*. }
Problem solved; the copy constructor receives the object by reference, yet in a way that is quasi-safe because the object is quasi-unmodifiable. (Quasi, because at some point, the mutable
keyword was invented to punch holes in const
objects.)