Variables of reference type must be initialized with an object of the type from which the reference type is derived, or with an object of a type that can be converted to the type from which the reference type is derived. For example:
int iVar;
long lVar;
long& LongRef1 = lVar; // No conversion required.
long& LongRef2 = iVar; // Converted to type long.
LongRef1 = 23L; // Change lVar through a reference.
LongRef2 = 11L; // Change iVar through a reference.
Once initialized, a reference-type variable always points to the same object; it cannot be modified to point to another object.
Although the syntax can be the same, initialization of reference-type variables and assignment to reference-type variables are semantically different. In the preceding example, the assignments that change iVar and lVar look similar to the initializations but have completely different effects. The initialization specifies the object to which the reference-type variable points; the assignment assigns to the referred-to object through the reference.
Because both passing an argument of reference type to a function and returning a value of reference type from a function are initializations, the formal arguments to a function are initialized correctly, as are the references returned.
The only time reference-type variables can be declared without initializers is in the following:
Function declarations (prototypes). For example:
int func( int& );
Function-return type declarations. For example:
int& func( int& );
Declaration of a reference-type class member. For example:
class c
{
public:
int& i;
};
Declaration of a variable explictly specified as extern. For example:
extern int& iVal;
When initializing a reference-type variable, the compiler uses the decision graph shown in Figure 7.4 (on the following page) to select between creating a reference to an object or creating a temporary object to which the reference points.
References to volatile types (declared as volatile typename& identifier) can be initialized with volatile or nonvolatile objects of the same type. They cannot, however, be initialized with const objects of that type. Similarly, references to const types (declared as const typename& identifier) can be initialized with const or nonconst objects of the same type (or anything that has a conversion to that type). They cannot, however, be initialized with volatile objects of that type.
References that are not qualified with either the const or volatile keyword can be initialized only with objects declared as neither const nor volatile.