RAD Studio
ContentsIndex
PreviousUpNext
Reference Arguments

The reference declarator can also be used to declare reference type parameters within a function:

void func1 (int i);
void func2 (int &ir);   // ir is type "reference to int"
    .
    .
    .
int sum = 3;
func1(sum);             // sum passed by value
func2(sum);             // sum passed by reference

The sum argument passed by reference can be changed directly by func2. On the other hand, func1 gets a copy of the sum argument (passed by value), so sum itself cannot be altered by func1. 

When an actual argument x is passed by value, the matching formal argument in the function receives a copy of x. Any changes to this copy within the function body are not reflected in the value of x outside the scope of the function. Of course, the function can return a value that could be used later to change x, but the function cannot directly alter a parameter passed by value. 

In C, changing the value of a function parameter outside the scope of the function requires that you pass the address of the parameter. The address is passed by value, thus changing the contents of the address effects the value of the parameter outside the scope of the function.  

Even if the function does not need to change the value of a parameter, it is still useful to pass the address (or a reference) to a function. This is especially true if the parameter is a large data structure or object. Passing an object directly to a function necessitates copying the entire object. 

Compare the three implementations of the function treble: 

Implementation 1  

int treble_1(int n)
{
   return 3 * n;
}
  .
  .
  .
int x, i = 4;
x = treble_1(i);  // x now = 12, i = 4
  .
  .
  .

Implementation 2

void treble_2(int* np)
{
   *np = (*np) * 3;
}
  .
  .
  .
treble_2(&i);    // i now = 2

Implementation 3

void treble_3(int& n)   // n is a reference type 
{
   n = n * 3;
}
  .
  .
  .
treble_3(i);             // i now = 36

The formal argument declaration type& t establishes t as type “reference to type.” So, when treble_3 is called with the real argument i, i is used to initialize the formal reference argument n. n therefore acts as an alias for i, so n = n*3 also assigns 3 * i to i. 

If the initializer is a constant or an object of a different type than the reference type, creates a temporary object for which the reference acts as an alias:

int& ir = 6;   /* temporary int object created, aliased by ir, gets value 6 */
float f;
int& ir2 = f;  /* creates temporary int object aliased by ir2; f converted
                  before assignment */
ir2 = 2.0      // ir2 now = 2, but f is unchanged

The automatic creation of temporary objects permits the conversion of reference types when formal and actual arguments have different (but assignment-compatible) types. When passing by value, of course, there are fewer conversion problems, since the copy of the actual argument can be physically changed before assignment to the formal argument.

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!