Parameter Passing Mechanisms Reference Parameters

advertisement
Parameter Passing
Mechanisms
Reference Parameters
Problem
Using OCD, design and implement a function
that, given a string containing a longdistance telephone number, decomposes that
number into its area code, exchange, and
local number.
Preliminary Analysis
Our function can receive the long-distance
phone number through a string parameter.
This problem requires that our function
somehow communicate three values (area
code, exchange, local number) to its caller.
A function cannot return multiple values -- the
return statement only returns one value:
return Expression ;
Behavior
Our program should receive from its caller a
long-distance phone number (a string).
It should check that the number is a valid
long- distance number. If so, it should
compute and pass back its area code,
exchange, and local number.
Objects
Description
long distance
number
area code
exchange
local number
Type
Movement
Name
string
in
ldNumber
string
string
string
out
out
out
areaCode
exchange
localNum
Operations
Description
Predefined? Library?
receive a string
yes
select part of
yes
a string
pass back 3 strings yes
Name
built-in
-string
substr
built-in
??
Algorithm
0. Receive ldNumber from caller, plus ‘empty’ variables
areaCode, exchange and localNum.
1. Check that ldNumber is a long-distance number.
2. Fill areaCode with appropriate substring of ldNumber.
3. Fill exchange with appropriate substring of ldNumber.
4. Fill localNum with appropriate substring of ldNumber.
Discussion
Since a function cannot return 3 strings,
we
will instead require the caller to pass us three
string variables, which our function will then
“fill in” with the appropriate values.
Normal parameters are called value parameters
and are built as copies of their arguments.
Changing a value parameter changes the copy,
not its corresponding argument.
Solution
Reference parameters are parameters declared
with an ampersand (&) following the
parameter’s type (and before its name).
A reference parameter is an alias (i.e., another
name for) its corresponding argument.
Changing the value of a reference parameter
changes the value of its corresponding
argument.
Coding
#include <string>
#include <cctype>
using namespace std;
// string class
// isdigit()
void ChopLDPhoneNumber(string ldNumber,
//
string & areaCode, //
string & exchange, //
string & localNum) //
{
for (int i = 0; i < ldNumber.size(); i++)
assert(isdigit(ldNumber[i]);
assert(ldNumber[0] == ‘1’ &&
ldNumber.size() == 11);
}
value: IN
reference: OUT
reference: OUT
reference: OUT
// check all
// digits
// check for leading 1
// check number of digits
areaCode = ldNumber.substr(1, 3);
exchange = ldNumber.substr(4, 3);
localNum = ldNumber.substr(7, 4);
Testing
The caller must now supply a variable for
each reference parameter, to be “filled in”
by the function.
cout << “Enter a L-D phone number: “;
string original, part1, part2, part3;
cin >> original;
ChopLDNumber(original, part1, part2, part3);
cout <<
<<
<<
<<
“\nArea code: “ << part1
“\nExchange: “ << part2
“\nLocal number: “ << part3
endl;
Notes
When function ChopLDNumber() is called:
– a copy of argument original is made to create
parameter ldNumber,
– an alias of argument part1 is made to create
parameter areaCode,
– an alias of argument part2 is made to create
parameter exchange,
– an alias of argument part3 is made to create
parameter localNum.
0. Before the function call
original
part1
part2
part3
16165551234
Memory
1. ldNumber is created
as a copy of original
original
part1
part2
part3
16165551234
16165551234
Memory
ldNumber
2. areaCode is created
as an alias for part1
original
part1
part2
part3
16165551234
areaCode
16165551234
Memory
ldNumber
3. exchange is created
as an alias for part2
original
part1
part2
part3
16165551234
areaCode
exchange
16165551234
Memory
ldNumber
3. localNum is created
as an alias for part3
original
part1
part2
part3
16165551234
16165551234
Memory
areaCode
exchange
localNum
ldNumber
4. The function checks
ldNumber for validity
original
part1
part2
part3
16165551234
16165551234
Memory
areaCode
exchange
localNum
ldNumber
5. The function computes
areaCode, changing part1
original
part1
part2
part3
16165551234
616
16165551234
Memory
areaCode
exchange
localNum
ldNumber
6. The function computes
exchange, changing part2
original
part1
part2
part3
16165551234
616
555
16165551234
Memory
areaCode
exchange
localNum
ldNumber
7. The function computes
localNum, changing part3
original
part1
part2
part3
16165551234
616
555
1234
16165551234
Memory
areaCode
exchange
localNum
ldNumber
8. The function returns,
destroying all parameters
original
part1
part2
part3
16165551234
616
555
1234
Memory
9. part1, part2, and part3
now contain the information!
original
part1
part2
part3
16165551234
616
555
1234
Memory
Notes
By default, parameters are value parameters.
Reference parameters are specified by placing
an ampersand after the parameter’s type.
Reference parameters must be specified in
both a function’s prototype and its
definition, or a linking error will occur.
Variables must be passed as arguments for
reference parameters to fill, or a compiler
error will occur.
Consider
Copying argument original consumes time.
Creating an alias for an argument takes almost
no time.
We could speed up calls to our function by
making parameter ldNumber a reference
parameter.
However, we then run the risk of changing
original if we mistakenly change ldNumber.
Solution
Constant reference parameters are reference
parameters whose declaration is preceded by
the keyword const.
void ChopLDPhoneNumber(const string & ldNumber,
string & areaCode,
string & exchange,
string & localNum)
// ...
//
//
//
//
IN
OUT
OUT
OUT
Const reference parameters are read-only
reference parameters -- aliases of their
arguments -- but they cannot be changed.
0. Before the function call
original
part1
part2
part3
16165551234
Memory
1. ldNumber is created as a
const reference of original
original
part1
part2
part3
16165551234 ldNumber
Memory
Conclusion
The rest of the function proceeds as before,
except that all accesses to ldNumber now
access original instead of the copy.
Any attempt to change ldNumber will generate a
compiler error (which makes sense, since its
movement is IN, not OUT).
Discussion
Copying time is not significant for simple types
(e.g., int, char, double, ...), but it is significant
for class types (e.g., string, RandomInt, ...).
Use reference parameters for arguments whose
movement is OUT.
Use const reference parameters to to store class
arguments whose movement is IN.
Use value parameters to store simple type
arguments whose movement is IN.
Summary
C++ provides 3 parameter mechanisms:
– value, used for IN parameters whose arguments
are simple types.
– const reference, for IN parameters whose
arguments are class types.
– reference, for all OUT parameters.
Download