In Hour 5, “Functions,” you learned that functions have two limitations: Arguments are passed by value, and the return statement can return only one value.
Passing values to a function by reference can overcome both of these limitations. In C++, passing by reference is accomplished in two ways: using pointers and using references. The syntax is different, but the net effect is the same: Rather than a copy being created within the scope of the function, the actual original object is passed into the function.
Passing an object by reference enables the function to change the object being referred to.
Listing 11.4 creates a swap function and passes in its parameters by value.
Main. Before swap. x: 5 y: 10 Swap. Before swap. x: 5 y: 10 Swap. After swap. x: 10 y: 5 Main. After swap. x: 5 y: 10
This program initializes two variables in main() and then passes them to the swap() function, which appears to swap them. But when they are examined again in main(), they are unchanged! |
The problem here is that x and y are being passed to swap() by value. That is, local copies were made in the function. What you want is to pass x and y by reference.
There are two ways to solve this problem in C++: You can make the parameters of swap() pointers to the original values, or you can pass in references to the original values.
When you pass in a pointer, you pass in the actual address of the object, and thus the function can manipulate the value at that address. To make swap() change the actual values using pointers, the function, swap(), should be declared to accept two int pointers. Then, by dereferencing the pointers, the values of x and y will, in fact, be swapped. Listing 11.5 demonstrates this idea.
Main. Before swap. x: 5 y: 10 Swap. Before swap. *px: 5 *py: 10 Swap. After swap. *px: 10 *py: 5 Main. After swap. x: 10 y: 5
Success! On line 3, the prototype of swap() is changed to indicate that its two parameters will be pointers to int rather than int variables. When swap() is called on line 11, the addresses of x and y are passed as the arguments. |
On line 19, a local variable, temp, is declared in the swap() function. Temp need not be a pointer; it will just hold the value of *px (that is, the value of x in the calling function) for the life of the function. After the function returns, temp will no longer be needed.
On line 24, temp is assigned the value at px. On line 25, the value at px is assigned to the value at py. On line 26, the value stashed in temp (that is, the original value at px) is put into py.
The net effect of this is that the values in the calling function, whose address was passed to swap(), are in fact swapped.
The preceding program works, but the syntax of the swap() function is cumbersome in two ways. First, the repeated need to dereference the pointers within the swap() function makes it error-prone and hard to read. Second, the need to pass the address of the variables in the calling function makes the inner workings of swap() overly apparent to its users.
It is a goal of C++ to prevent the user of a function from worrying about how it works. Passing by pointers puts the burden on the calling function which is not where it belongs. The calling function must know to pass in the address of the object it wants to swap.
The burden of understanding the reference semantics should be on the function implementing the swap. To accomplish this, you use references. Listing 11.6 rewrites the swap() function using references. Now the calling function just passes in the object, and because the parameters are declared to be references, the semantics are pass by reference. The calling function doesn't need to do anything special.
Main. Before swap, x:5 y: 10 Swap. Before swap, rx:5 ry:10 Swap. After swap, rx:10 ry:5 Main. After swap, x:10, y:5
When swap() is called, program execution jumps to line 18, where the variables are identified as references. Their values are printed on lines 22 and 23, but note that no special operators are required. These are aliases for the original values, and can be used as such.
On lines 25–27 the values are swapped, and then they're printed on lines 29 and 30. Program execution jumps back to the calling function, and on lines 13 and 14 the values are printed in main(). Because the parameters to swap() are declared to be references, the values from main() are passed by reference, and thus are changed in main() as well.
References provide the convenience and ease of use of normal variables, with the power and pass-by-reference capability of pointers!
18.189.188.238