C++ References1

Jeffrey D. Oldham

2000 Mar 25

Caveat Reader!

I wrote this notes to prepare myself for lecture. The topic of returning references from functions is not well documented, even in the C++ language definition so I have used my experience to guess the rules.

Introduction

A C++ reference is used when:

Reference Parameters

This program illustrates these uses for reference parameters. ./regular-references.cc

For foo to set the value of the first parameter it must be passed by reference.

istreams and ostreams may not be copied so the second parameter must be passed by reference.2

foo's last parameter is passed by reference so the string need not be copied. Not copying the string saves time proportional to the number of characters in the string. Since we are passing the string by reference but we do not want the string to be copied, we mark it const. Thus, foo can inspect and use the string, but it may not change its contents. For more information, read the textbook, pp. 66-67.

Returning References

A function may return a reference for exactly the same reasons:

This program illustrates these uses for reference parameters. ./return-references.cc The foo class holds a dynamically-allocated array of strings. Thus, we need a destructor, a copy constructor, and an assignment operator. We also define two element access functions and an output operator.

The statement f[2] = "hello" illustrates changing the return value. Equivalent code with an explicit function call is f.operator[](2) = "hello". The result of f.operator[](2) is assigned a value so it must be a reference, not a value.

The operator[] function obeys the two rules for functions returning references. Any function having return type T & must follow two rules:

operator[] obeys the first rule because it returns a member of a string array. It obeys the second rule because it returns a reference to a position in the object's array, not the function's only variable i.

The const version of operator[] guarantees that the returned result is not changed. It returns a reference to avoid copying the return value since copying a very long string may be very expensive but marks it const so it is not changed. The second occurrence of const guarantees that any call to this function does not change the object's contents. Defining this const version is necessary so that functions with const foo variables or parameters can access their array elements.

Tip: Whenever defining a function returning a reference to a variable inside an object, define a const version that will also work with const objects.

As mentioned above, ostreams may not be copied. Thus, the output operator must return a reference so its return value is not copied. The expression it returns has ostream type and is defined outside the function so returning out is permissible.



Footnotes

... References1
©2000 Jeffrey D. Oldham . All rights reserved. This document may not be redistributed in any form without the express permission of the author.
... reference.2
Each istream object tracks the position of the next character to read. If a function was given a copy of an istream object, it could read from the stream. Then the main function could read the same characters again! Thus, helper functions to read input would be mostly useless. By using only references to istream objects, all functions refer to the same object; if one reads some characters changing the position, all change the position. Similar reasoning applies to ostreams.



2000-03-26