CS210 Lab: Operator Overloading and "This"--Intro to "this"


For an introduction to "this" on the computer science department web pages, click here

What is "this"?

Let's take a look a the myarray class and specifically the setvalue function.
class myarray 
{
private:
	int value[MAXARRAY];

public:
	void setvalue(int index, int newvalue){
		value[index]=newvalue;}
	...
};

int main ()
{
	myarray array1, array2, array3;
	
	//INITIALIZE 
	for (int i=0; i<MAXARRAY; i++)
	{
		array1.setvalue(i,i);
		array2.setvalue(i,i+3);
	}
	...	
}
In memory, you can view array1 and array2 objects as occupying separate space.

When you make a call to setvalue, how does it know which value array you are talking about?

For instance, how does the following call know that you are referring to array1's value array:

	array1.setvalue(0,0);
The reason is because whenever a member function is called, an implicit argument is sent to point to the object that called (or invoked) the member function. This pointer is called this

Let's look at more details (the following text, with the exception of the sample code, is copied from page 637 of C++ Primer by Stanley B. Lippman and Josee Lajoie).

One way of understanding this is to take a brief look at how a compiler implements the this pointer. There are two transformations that must be applied to support the this pointer:
  1. Translate the definition of the class member function. Each class member function is defined with one additional parameter: the this pointer. For example:
    //pseudocode that illustrates the compiler expansion
    //of a member function definition --
    //not legal C++ code
    
    	void setvalue(myarray* this, int index, int newvalue){
    		this->value[index]=newvalue;}
    
    In the member function, the use of the this pointer to access the class data member [value] is made explicit.

  2. Translate each invocation of the class member function to add an additonal argument -- the address of the object for which the member function is invoked. For example,
    	array1.setvalue(0,0);
    
    is translated into
    	setvalue(&array1,0,0);
    
The programmer can refer to the this pointer explicitly in a member function definition. For example, it is legal although unnecessary to define the member function [getvalue] as follows:
	int getvalue(int index){
		return this->value[index];}

Related back to operator overloading

When we have overloaded the addition operator as a member function, and the compiler sees,
array3=array1 + array2;   //we write
it interpretes it as
array3=array1.operator+(array2); //compiler interpretation 
And because of the this pointer it is further interpreted as
array3=operator+(&array1,array2); //futher compiler interpretation
So, we are back to having two arguments or operands sent to the overloaded addition operator.


Where does "this" come in handy?

It is very useful when you want to refer to the object that called the member function or return that object. Let's use an example:
#include <iostream>
using namespace std;

#define MAXARRAY 5

class myarray 
{
private:
	int value[MAXARRAY];

public:
	void setvalue(int index, int newvalue){
		value[index]=newvalue;}
	int getvalue(int index){
		return value[index];}

	// pass by reference so that a copy isn't made
	// use "const" so that it isn't modified
	myarray operator=(const myarray &array2)
	{
		// Can check if both sides are equal, 
		// then don't have to do anything, just return
		if (this!=&array2)
		{
			for (int i=0; i<MAXARRAY; i++)
				value[i]=array2.value[i];
		}
		return *this;
	}
};

int main ()
{
	int i;
	myarray array1, array2, array3;
	
	//INITIALIZE 
	for (i=0; i<MAXARRAY; i++)
	{
		array1.setvalue(i,i);
		array2.setvalue(i,i+3);
	}
	
	//ASSIGN
	array3=array1=array2;   
	//array3 and array1 now equal array2 

	
	//PRINT 
	cout << "array1   array2   array3" << endl;
	for (i=0; i<MAXARRAY; i++)
		cout << array1.getvalue(i) << "        " 
		     << array2.getvalue(i) << "        " 
		     << array3.getvalue(i) << endl;

	cout << endl;
	cout << "address of the three arrays:" << endl;
	cout << "array1   array2   array3" << endl;
	cout << &array1 << "  " << &array2 << "  " 
		<< &array3  << endl;
	return 0;
}
A couple of things to note from this are:
  1. An assignment in main such as: array1=array2, will send the address of the array1 object--interpreted as the this pointer. In the overloaded "operator=" function, in order to compare the two objects (to ensure they are not the same). You must say:
    		if (this!=&array2)
    	
    Ultimately, this compares the address of array1 to the address of array2.

  2. In order to have multiple assignments in main such as: array3=array1=array2;, you must return a myarray object to make it work. Therefore, you
    		return *this;
    	
    The operations are carried out so that array1=array2 is first completed and array1 is returned (through this). Then, array3=array1 is carried through. (Note that the later reference to array1 has been assigned the values of array2)

Back to the Operator Overloading and "This" Lab click here

CS Dept Home Page
CS Dept Class Files
CS210 Class Files

Copyright: Department of Computer Science, University of Regina.