Functions
In C++, a function is a group of statements that is given a name, and which can be called from some point of the program. The most common syntax to define a function is:
type name ( parameter1, parameter2, ...) { statements }
Where:
-
type
is the type of the value returned by the function.-
name
is the identifier by which the function can be called.-
parameters
(as many as needed): Each parameter consists of a type followed by an identifier, with each parameter being separated from the next by a comma. Each parameter looks very much like a regular variable declaration (for example: int x
), and in fact acts within the function as a regular variable which is local to the function. The purpose of parameters is to allow passing arguments to the function from the location where it is called from.-
statements
is the function's body. It is a block of statements surrounded by braces { } that specify what the function actually does.Arguments passed by value and by reference
In the functions seen in earlier sessions, arguments have always been passed by value. This means that, when calling a function, what is passed to the function are the values of these arguments on the moment of the call, which are copied into the variables represented by the function parameters. For example, take:
|
|
In this case, function addition is passed 5 and 3, which are copies of the values of
x
and y
, respectively. These values (5 and 3) are used to initialize the variables set as parameters in the function's definition, but any modification of these variables within the function has no effect on the values of the variables x and y outside it, because x and y were themselves not passed to the function on the call, but only copies of their values at that moment.In certain cases, though, it may be useful to access an external variable from within a function. To do that, arguments can be passed by reference, instead of by value.
&
) following the parameter type, as in the parameters taken by duplicate
in the example above.When a variable is passed by reference, what is passed is no longer a copy, but the variable itself, the variable identified by the function parameter, becomes somehow associated with the argument passed to the function, and any modification on their corresponding local variables within the function are reflected in the variables passed as arguments in the call.
If instead of defining duplicate as:
|
|
Was it to be defined without the ampersand signs as:
|
|
The variables would not be passed by reference, but by value, creating instead copies of their values. In this case, the output of the program would have been the values of
x
, y
, and z
without being modified (i.e., 1, 3, and 7).Efficiency considerations and const references
Calling a function with parameters taken by value causes copies of the values to be made. This is a relatively inexpensive operation for fundamental types such asint
, but if the parameter is of a large compound type, it may result on certain overhead. For example, consider the following function:
|
|
This function takes two strings as parameters (by value), and returns the result of concatenating them. By passing the arguments by value, the function forces
a
and b
to be copies of the arguments passed to the function when it is called. And if these are long strings, it may mean copying large quantities of data just for the function call.But this copy can be avoided altogether if both parameters are made references:
|
|
Arguments by reference do not require a copy. The function operates directly on (aliases of) the strings passed as arguments, and, at most, it might mean the transfer of certain pointers to the function. In this regard, the version of
concatenate
taking references is more efficient than the version taking values, since it does not need to copy expensive-to-copy strings.On the flip side, functions with reference parameters are generally perceived as functions that modify the arguments passed, because that is why reference parameters are actually for.
The solution is for the function to guarantee that its reference parameters are not going to be modified by this function. This can be done by qualifying the parameters as constant:
|
|
By qualifying them as
const
, the function is forbidden to modify the values of neither a
nor b
, but can actually access their values as references (aliases of the arguments), without having to make actual copies of the strings.Therefore,
const
references provide functionality similar to passing arguments by value, but with an increased efficiency for parameters of large types. That is why they are extremely popular in C++ for arguments of compound types. Note though, that for most fundamental types, there is no noticeable difference in efficiency, and in some cases, const references may even be less efficient!
No comments:
Post a Comment