• No results found

1 inline vector & vector::operator +=( 2 vector &rightOperand)

3 {

4 x += rightOperand.x; 5 y += rightOperand.y; 6 return (*this);

7 } 8

9 inline vector & vector::operator -=( 10 vector &rightOperand) 11 { 12 x -= rightOperand.x; 13 y -= rightOperand.y; 14 return (*this); 15 } 16

17 inline vector & vector::operator *=( 18 int rightOperand) 19 { 20 x *= rightOperand; 21 y *= rightOperand; 22 return (*this); 23 } 24

25 inline vector & vector::operator /=( 26 int rightOperand) 27 { 28 x /= rightOperand; 29 y /= rightOperand; 30 return (*this); 31 }

The operator-equals operator functions in Listing 5.3 each use the operator- equals operators for the vector components. For instance, the operator +=()

function on lines 17 uses the += operator for integers to add the x component

of the right operand to the x component of the left operand and store the result in the left operand. It does the same on line 5 for the y components. These four operator functions work differently than any we've discussed so far. First, they do not declare temporary variables. Second, they return something called *this. Third, the return type is vector &, not just vector. It's natural to wonder

what all this means.

To understand what's happening here, let's first look at what happens when your functions return values. Normally, the value a function returns is

automatically copied into a special area of memory called the program stack. The program uses its stack to store values that functions return. We can see how the stack works by looking back at the vector::X() function whose prototype is

on line 11 of Listing 5.2 I'll repeat its code here for convenience:

inline int vector::X(void) {

return (x); }

This function does nothing but return a value. Suppose a program contains statements like the following:

vector v1(10,20); int thisInt = v1.X();

When the program executes the statement

int thisInt = v1.X();

it calls the X() function. The X() function in turn returns the value of v1's private

data member x. When it does, the program automatically copies the value

being returned onto the stack. It then jumps back to the point at which the X()

function was called. Of course, that point was the statement

int thisInt = v1.X();

The value being returned is still on the program's stack. The assignment operator (=) causes that value to be copied into the variable thisInt. The value

on the stack is then thrown away, but that's okay because the program copied it into a variable. That's how things normally work when your function returns a value.

It is possible for function to bypass the normal mechanisms of returning a valuewhich is what's happening in Listing 5.3 with the operator-equals

functions. Whenever the return type of a function is followed by an ampersand (&), it means that the function returns a reference instead of a value. When a

function returns a reference, it returns an actual variable rather than a copy of the variable.

What does this all mean?

Look once more at how programs use the += operator. If your program

contains the statements

v1+=v2;

then it is changing the contents of v1, and the results of the addition are stored

there. If you write the operator +=() function for the vector class like this:

inline vector vector::operator +=( vector &rightOperand) { vector temp; temp.x = x + rightOperand.x; temp.y = y + rightOperand.y; return (temp); }

This function has a problem. Do you see what it is?

In this example, the operator +=() function declares a variable called temp, which

stores the results of the addition. The function then returns that variable. But the whole idea behind the += operator is to change the variable that called the

function.

This version of the operator +=() function does not do that. At no time does it

change the x or y value of the left operand.

"Well," you might say, "that's easy to fix. Just write it like you had it before, but return a vector instead of a vector &." If we did that, the code would look like

this:

inline vector vector::operator +=( vector &rightOperand)

{

x += rightOperand.x; y += rightOperand.y; }

What happened to the return statement? It's gone. When we get rid of the

temporary variable temp, we no longer have anything to return. "That's okay,"

to, but you need to. According to the normal rules of C++, all operator-equals functions must return a value. This enables you to write statements such as

vector v1(10,20), v2(20,30), v3; v3 += v2 += v1;

C++ does not force you to return a value from an operator +=() function.

However, if you don't, other programmers will have problems with your code. They expect all operator +=() functions to return a value.

To solve this problem, the operator +=() function must return the left operand. The

way it does that is with the statement

return (*this);

This statement is a way of saying, "Return this object." And in all cases, "this object" is the one that called the function.

If a function contains the statement

return (*this);

it cannot return a copy of an object. It must return a reference to an object instead. That's why the operator-equals functions in Listing 5.3 all return references. They have to bypass the normal return mechanisms and return a reference rather than a value because they all end with the statement

return (*this);

By using a reference for the return type, and by returning *this, your operator-

equals functions all work properly. Your functions can change the contents of the left operand. They let you write statements such as

in your programs. This is how operator-equals functions are supposed to work.