Lecture Notes for SE 598, Data Structures and Algorithms
31 May 2000, C++ Functions
- functions
- encapsulates transformations on data structures
- default argument values -
- formal parameters may include a default value
- for example,
int open(string name, string mode = "r")
- actual parameters corresponding to formal parameters with defaults may
be omitted in function calls
-
open("mbox", "r")
-
open("mbox")
-
open("mbox", "w")
- any formal parameter with defaults must appear after every formal
parameter without defaults
- wrong:
int set_time(int hour = 0, int minute, int second = 0)
- right:
int set_time(int hour, int minute, int second = 0)
- right:
int set_time(int hour = 0, int minute = 0, int second = 0)
- default formal parameter values interact with default object
constructors
- reference parameters
- call-by-value vs. call-by-reference
- call-by-value passes a copy of the actual parameter
- call-by-reference passes the address of the actual parameter
- call-by-value is safer than call-by-reference
- call-by-value is less efficient than call-by-reference
- pointers vs. references
- in C, call-by-reference is implemented using the pointer-to
*
and address-of &
operators
- definition:
void swap(int * ap, int * bp) { ... }
- call:
swap(&i, &j)
- C++ can also use the reference type to implement call-by-reference
- definition:
void swap(int & a, int & b) { ... }
- call:
swap(i, j)
- reference parameters
- reference-type call-by-reference is preferred over address-of and
pointer-to call-by-reference
- eliminating
*
and &
makes things easier and simpler
- constant reference parameters
- some measure of call-by-value security can be regained by using
constant reference formal parameters
-
void search(const tree_node & root, int x) { ... }
- however -
const
-ness can be cast away
- stl makes heavy use of reference and const reference types in
parameters
- const reference and reference types are different; confusing them
can lead to confusing compile time errors.
- there are also subtle interactions between const reference and
reference formal parameters and object creation
- overloading
- a function's signature is the left-to-right listing of its formal
parameter types
- for example, the function
int table(int x, table & t, string &
s)
has signature (int, table &, string &)
.
- formal parameter names and the return type are not part of the
signature
- if a function is characterized by its name and its signature, then two
functions can have the same name as long as they have different
signatures
-
int table(int x, table & t, string & s) { . . . }
-
int table(int x, const table & t, string & s) { . . . }
-
int table(int x, const table & t, string s) { . . . }
- two or more functions of the same name but different signatures are
said to be overloaded functions
- operators are functions, and so can also be overloaded
- definition:
string operator*(string & s, int m) { . . . })
- use:
cout << string("|")*3
- the operators
.
, ::
, and ?:
can't be overloaded
- the operation's arity can't be changed
- C++ objects and the stl make heavy use of overloading
- templates
- creating more than a small number of overloaded functions can quickly
get tedious
-
void swap(int & i, int & j) { . . . }
-
void swap(double & i, double & j) { . . . }
-
void swap(string & i, string & j) { . . . }
- function templates avoid this problem by parameterizing functions by
type
-
template <typename T> void swap(T & i, T & j) { . . . }
- the C++ compiler expands each use of the function using its templated
definition as a pattern
- each template typename must appear at least once in the function's
formal parameter list
- template functions cannot be split into prototype and body, and they
must be defined in each file they are used
- the STL makes heavy use of template functions
This page last modified on 31 May 2000.