@Eric M:
Passing references to a function for the purpose of receiving [out] data is evil because the syntax of the code at the calling site does not indicate (to the programmer) that the object being passed into the function may be modified across the function call.
void foo(int& bar);
int n = 42;
foo(n); // No syntactic hint that 'n' may be modified by this call!
In this example, it is not at all obvious that foo() can modify the value of the local variable 'n' unless you examine the prototype and/or implementation of foo(). This makes it more difficult to understand what this code is doing.
If foo() is not intended to modify the parameter, it should be a const reference: void foo(const int& bar); if it does modify the parameter, the caller should be required to use pointer notation in order to emphasize this possible side-effect at the call site: void foo(int *bar);
This is not just a matter of coding style, but can have an impact on the efficiency of the code generated. If you pass an object by non-const reference, the compiler MUST assume that the object has been modified in the call and must reload any cached data that was previously loaded from that object. Although programmers should not waste mental energy fussing over the efficiency of every line of code, we also should not employ constructs that unnecessarily prevent the compiler from performing whatever optimizations it can.
Aside from syntactic convenience, the other "advantage" of references is that the compiler will go to great lengths to ensure that a reference does not contain a NULL pointer. So one might argue that using a reference means that foo() does not need to check for a NULL pointer. However, it is still possible for the caller to attempt to pass a NULL object to this function, which will cause an exception:
int *bar = NULL;
foo(*bar); // This will throw an exception at runtime!
So instead of locally handling the possibility of a NULL object pointer and encapsulating any error handling, use of reference parameters simply pushes this problem out onto the caller.
In short, there is never a good reason to pass any parameter to a function by non-const reference; this can always be replaced by either a const reference or a pointer.