Reference-Type Function Arguments

It is often more efficient to pass references, rather than functions, to large objects. This allows the compiler to pass the address of the object while maintaining the syntax that would have been used to access the object. Consider the following example that uses the Date structure:

// Create a Julian date of the form DDDYYYY
// from a Gregorian date.
long JulianFromGregorian( Date& GDate )
{
    static int cDaysInMonth[] = {
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    long JDate;

    // Add in days for months already elapsed.
    for( int i = 0; i < GDate.Month - 1; ++i )
        JDate += cDaysInMonth[i];

    // Add in days for this month.
    JDate += GDate.Day;

    // Check for leap year.
    if( GDate.Year % 100 != 0 && GDate.Year % 4 == 0 )
        JDate++;

    // Add in year.
    JDate *= 10000;
    JDate += GDate.Year;

    return JDate;
}

The preceding code shows that members of a structure passed by reference are accessed using the member-selection operator (.) instead of the pointer member-selection operator (–>).

Although arguments passed as reference types observe the syntax of nonpointer types, they retain one important characteristic of pointer types: they are modifiable unless declared as const. Because the intent of the preceding code is not to modify the object GDate, a more appropriate function prototype is:

long JulianFromGregorian( const Date& GDate );

This prototype guarantees that the function JulianFromGregorian will not change its argument.

Any function prototyped as taking a reference type can accept an object of the same type in its place because there is a standard conversion from typename to typename&.