FAQs in section [8]:
[8.1] What is a reference?
An alias (an alternate name) for an object.
References are frequently used for pass-by-reference:
void swap(int& i, int& j)
{
int tmp = i;
i = j;
j = tmp;
}
int main()
{
int x, y;
// ...
swap(x,y);
}
Here i and j are aliases for main's x and y respectively. In other
words, i is x not a pointer to x, nor a copy of x, but x
itself. Anything you do to i gets done to x, and vice versa.
OK. That's how you should think of references as a programmer. Now, at the
risk of confusing you by giving you a different perspective, here's how
references are implemented. Underneath it all, a reference i to object x
is typically the machine address of the object x. But when the programmer
says i++, the compiler generates code that increments x. In
particular, the address bits that the compiler uses to find x are not
changed. A C programmer will think of this as if you used the C style
pass-by-pointer, with the syntactic variant of (1) moving the & from the
caller into the callee, and (2) eliminating the *s. In other words, a C
programmer will think of i as a macro for (*p), where p is a
pointer to x (e.g., the compiler automatically dereferences the underlying
pointer; i++ is changed to (*p)++; i = 7 is
automatically changed to *p = 7).
Important note: Even though a reference is often implemented using an
address in the underlying assembly language, please do not think of a
reference as a funny looking pointer to an object. A reference is the
object. It is not a pointer to the object, nor a copy of the object. It
is the object.
[ Top | Bottom | Previous section | Next section ]
[8.2] What happens if you assign to a reference?
You change the state of the referent (the referent is the object to which the
reference refers).
Remember: the reference is the referent, so changing the reference
changes the state of the referent. In compiler writer lingo, a reference is an
"lvalue" (something that can appear on the left hand side of an assignment
operator).
[ Top | Bottom | Previous section | Next section ]
[8.3] What happens if you return a reference?
The function call can appear on the left hand side of an assignment operator.
This ability may seem strange at first. For example, no one thinks the
expression f() = 7 makes sense. Yet, if a is an object of
class Array, most people think that a[i] = 7 makes sense even
though a[i] is really just a function call in disguise (it calls
Array::operator[](int), which is the subscript operator for class
Array).
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)
}
[ Top | Bottom | Previous section | Next section ]
[8.4] How can you reseat a reference to make it refer to a
different object?
No way.
You can't separate the reference from the referent.
Unlike a pointer, once a reference is bound to an object, it can not be
"reseated" to another object. The reference itself isn't an object (it has no
identity; taking the address of a reference gives you the address of the
referent; remember: the reference is its referent).
In that sense, a reference is similar to a const
pointer such as int* const p (as opposed to a pointer to const such as const int* p). In spite of the gross
similarity, please don't confuse references with pointers; they're not at
all the same.
[ Top | Bottom | Previous section | Next section ]
[8.5] When should I use references, and when should I use pointers?
Use references when you can, and pointers when you have to.
References are usually preferred over pointers whenever you don't need
"reseating". This usually means that references are
most useful in a class's public interface. References typically appear on
the skin of an object, and pointers on the inside.
The exception to the above is where a function's parameter or return value
needs a "sentinel" reference. This is usually best done by returning/taking a
pointer, and giving the NULL pointer this special significance (references
should always alias objects, not a dereferenced NULL pointer).
Note: Old line C programmers sometimes don't like references since they provide
reference semantics that isn't explicit in the caller's code. After some C++
experience, however, one quickly realizes this is a form of information hiding,
which is an asset rather than a liability. E.g., programmers should write code
in the language of the problem rather than the language of the machine.
[ Top | Bottom | Previous section | Next section ]
E-mail the author
[ C++ FAQ Lite
| Table of contents
| Subject index
| About the author
| ©
| Download your own copy ]
Revised Jul 10, 2000
|