void add3(int* xptr) {
*xptr = *xptr + 3;
}
That works, but can be a bit annoying because we have to use the dereference
operator * all over the place in our function. Besides that, we have to
remember to add the address-of operator wherever we might call this function,
like:
int a = 10;
add3(&a);
add3(&a);
// now a equals 16
Since pointers can be tricky and sometimes “dangerous” to use, C++ tries to
avoid some of the situations where we might have to use them. The answer in
this case is to use a reference variable as the parameter to the add3 function,
like so:
void add3(int& x) {
x = x + 3;
}
Specifying a reference type is similar to specifying a pointer type, except you
use an & with the type instead of a *. What that means is that the x passed to
the function is a reference to whatever variable the function is called on.
Changing x in the function, when x is a reference variable, also changes the
original value!
int a = 10;
add3(a); // works now, no pointer needed!
add3(a);
// now a = 16
Pass by reference is also used in C++ to return multiple values from a function
(by passing in multiple arguments by reference), or to avoid copying something
that is large or otherwise wouldn’t make sense to copy.
ostream and istream) by reference.
Compared to using pass-by-address, we can write the same code much simpler
using pass-by-reference.
int readtime(istream&);
...
int readtime(istream& in)
{
int h, m, s;
char c;
in >> h >> c >> m >> c >> s;
return h*3600 + m*60 + s;
}
As you see, the function reads the elapsed amount of time in our
hh:mm:ss format.
With these definitions, we can say
int k = readtime(cin);
when we need to read in a time from the keyboard.
Note: Both cin and all the ifstream objects
can be passed as a reference to istream.
Therefore, we can also say:
ifstream fin("data.txt");
int m = readtime(fin); // pass fin as a reference to istream
... when we need to read in a time from a file data.txt
using the same function readtime.
It would be wonderful to have a function readtime that can take
either cin or fin as an argument, read the elapsed
time in hh:mm:ss format, and return it in seconds.
Although, this is not going to be a major theme for this course, we'd like to
show it to you so that you understand that we really can build new types in C++
if we want to. Also, we should note, this is why + and >> and so on work
with C++ string objects. The implementers of the string library
defined all these operators for their nice string type.
q to quit.
|
First solution. A first solution is a
pretty simple program.
The meat the program is: |
Operator overloading.
While it may be simple, it would be nice to be able to write the function as if
point were a built-in type, meaning that we could add points
p and m by saying p + m.
|
|
|
p + m means for point objects
p and m. Doing this is quite easy once you
understand the following:
a + b is just the same as the function call
operator+(a,b) in C++.
So if you want to tell the compiler what + means for two
point objects, you need to define the function
operator+(point a,point b) --- i.e. overload the
+ operator for points. The prototype is
clear:
point operator+(point a, point b);
... at least it is hopefully clear that we should return a point when
we add two points. The function definition is ... just like any
other function definition:
point operator+(point a, point b)
{
point S;
S.x = a.x + b.x;
S.y = a.y + b.y;
return S;
}
point struct over and over, and
you'll like being able to add points. Wouldn't it be nice to
define the midpoint function like this:
point midpoint(point a, point b)
{
return (a + b)/2.0;
}
A Π B,
where "Π" stands for some operator, then that is equivalent
to a function call operatorΠ(A,B).
So, to subtract two points we'd define
point operator-(point A, point B);
... and to compare two points with less than we'd define
bool operator<(point A, point B);
... or to multiply a point (on the left) by a real number (on
the right) we'd define
point operator*(point A, double w);
operator+ for two
point objects, what else would you need?
Well, (a + b) is an object of type
point, and we are dividing it by an object of type
double, so we need to define
operator/(point,double). What type of object should
be returned here?
point operator/(point P, double z)
{
point Q;
Q.x = P.x / z;
Q.y = P.y / z;
return Q;
}
istream& operator>>(istream &in, point &A)
{
char c;
return in >> c >> A.x >> c >> A.y >> c;
}
ostream& operator<<(ostream &out, point A)
{
return out << '(' << A.x << ',' << A.y << ')';
}
The prototypes of these two should actually make some sense.
For example, we've talked before about how cin >> x
actually evaluates back to cin.
To wrap all of this function overloading stuff up, consider this example: point.h and point.cpp.