course of C++ programming language

lecture 2: references


What is reference?

A reference is an alternative name for an object. A reference is like a constant pointer that is automatically dereferenced. It is usually used for function argument lists and function return values. But you can also make a free-standing reference.

int x = 77; int &ref = x; // ref and x now refere to the same int cell ref = 33; // this is equivalent to x = 33;

There are certain rules when using references:

  • A reference must be initialized when it is created (pointers can be initialized at any time). To ensure that a reference is a name for something (that is, bound to an object), we must initialize the reference.
  • Once a reference is initialized to an object, it cannot be changed to refer to another object (pointers can be pointed to another object at any time).
  • You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
int i = 1; int &r1 = i; // ok: r1 initialized int &r2; // error: initializer missing extern int &r3; // ok: r3 initialized elsewhere
Reference parameters

Probably the most important use for a reference is to allow you to create functions that automatically use call-by-reference parameter passing. Arguments can be passed to functions in one of two ways: using call-by-value or call-by-reference. When using call-by-value, a copy of the argument is passed to the function. Call-by-reference passes the address of the argument to the function. By default, C++ uses call-by-value, but it provides two ways to achieve call-by-reference parameter passing. First, you can explicitly pass a pointer to the argument. Second, you can use a reference parameter.

void neg_ptr (int *p) { *p = -*p; } void neg_ref (int &p) { p = -p; }

When a reference is used as a function argument, any modification to the reference inside the function will cause changes to the argument outside the function. Of course, you could do the same thing by passing a pointer, but a reference has much cleaner syntax.

Returning reference

A function may return a reference. This has the rather startling effect of allowing a function to be used on the left side of an assignment statement!

# include <iostream> using namespace std; char & replace (char tab[], int i); // return a reference int main() { char s[80] = "Hello There"; replace(5) = 'X'; // assign X to space after Hello cout << s << endl; return 0; } char & replace (char tab[], int i) { return tab[i]; }

One thing to beware of when returning a reference is that the object being referred to does not go out of scope after the function terminates.

Pointer reference

The function argument becomes a reference to a pointer, and you no longer have to take the address of that pointer.

void fun (int *&pr);
Constant reference

The obvious implementation of a reference is as a (constant) pointer that is dereferenced each time it is used.

Initialization of a reference is trivial when the initializer is an lvalue (an object whose address you can take). The initializer for a plain T& must be an lvalue of type T. The initializer for a const T& need not be an lvalue or even of type T. In such cases:

  1. first, implicit type conversion to T is applied if necessary;
  2. then, the resulting value is placed in a temporary variable of type T; and
  3. finally, this temporary variable is used as the value of the initializer.

Consider:

double &dr = 1; // error: lvalue needed const double &cdr = 1; // ok

The interpretation of this last initialization might be:

double temp = double(1); // first create a temporary with the right value const double &cdr = temp; // then use the temporary as the initializer for cdr

A temporary created to hold a reference initializer persists until the end of its reference's scope.

Restrictions to references

There are a few of restrictions that apply to references. You cannot reference another reference. Put differently, you cannot obtain the address of a reference. You cannot create arrays of references. You cannot create a pointer to a reference. You cannot reference a bit-field.


References
  1. B.Stroustrup: The C++ programming language. Third edition.
    Section 5: pointers, arrays and structures; pp. 97-100.
  2. Bruce Eckel: Thinking in C++. Second edition.
    Section 11: references and copy-constructor; pp. 449-455.