Section 3 - The THIS Pointer

1B.3.1 Review of this

The material in this section should be review for those of you who had CS 2A, but I present it here for reference if you need it.

Let's consider a hypothetical class, Rectangle, whose class prototype looks something like this:

// class Rectangle prototype ---------------
class Rectangle
{
private:
    double width, height;

public:
    bool setWidthHeight(double width, double height);

    // rest of class prototype omitted ...
}

The definition of the instance method setWidthHeight() might look like this:

bool Rectangle::setWidthHeight(double w, double h)
{
    if ( w <= 0 || h <= 0 )
    {
        // don't allow negative width or height
        return false;
    }
    width = w;
    height = h;
    return true;
}

We called the formal parameters w and h. Not very informative (I deduct points for this sort of variable or object naming). Really, what we are passing in is the width and height of the rectangle. So why don't we call these parameters width and height?  We could try:

bool Rectangle::setWidthHeight(double width, double height)
{
    if ( width <= 0 || height <= 0 )
    {
	// don't allow negative width or height
	return false;
    }
    else
    {
	width = width;    // oops!
	height = height;
        return true;
    }
}

See what happened? We named the formal parameters the same as the instance variables. Before, when we used the term width inside an instance method we meant the private data width of the calling object. But now we have a parameter with the same name, so there is ambiguity.

scenic boat

Recall that parameters are really just ordinary local variables or object references. They are very similar to the variables or objects declared inside the function, the only difference being that parameters get assigned values automatically when the function is called (via the arguments passed down through the function call). Now, let's recall a fact about any local variable (be it a parameter or ordinary variable defined in the function):

 Variable Hiding

When we declare a local variable, if it has the same name as an instance member, this local variable hides or shadows the instance member throughout the method definition.

What this means is that if we use the term width inside our newly formed method, we would be referring to the local width, not the member width.

But what if we want to name the formal parameter width and also refer to the member width later in the method? There is a hidden reference identifier called "this" that all instance methods can use. this can be used to access any of the instance members by dereference. So, even though the formal parameter width shadows the member width, making it seem inaccessible, we can still "get at" that member using the "this->" notation:

this->width = width;
this->height = height;

Now we are safe. The LHS, this->width, refers to the member width of the calling object.  The RHS, width, refers to the formal parameter width of that same name..  If you already know about pointers, a topic we will cover next week, you can see from the notation that this is actually a pointer to the object that was used to call the method we are in.  That's why we use the pointer notation, ->.

We can name formal parameters the same as members if it makes sense to do so and still have a way to get at the members. 

Here is how the method will look, once we have used this improved notation:

bool Rectangle::setWidthHeight(double width, double height)
{
    if ( width <= 0 || height <= 0 )
    {
	// don't allow negative width or height
	return false;
    }
    else
    {
	this->width = width;
	this->height = height;
	return true;
    }
}

When we enter any instance method, some object must have been used to get us there, and that object is called the "this" object

We can always place the "this" keyword inside any instance method wherever there are member variables or methods that would otherwise be floating free without objects to dereference them.  Sometimes programmers use this->member rather than just member, even when there is no ambiguity to resolve.  It helps them remember that they are looking at member variables, not variables local to the method.