Sunday 29 May 2016

The this pointer in C++

The this pointer has a special place in C++. Even though one doesn't get to hear a lot about these, they are always there in a class in C++, always. But before getting into what a this pointer is, let us first start with a normal type of pointer, pointing all so innocently to an object of a class:
class student
{};
student *p;
student obj;
p= &obj;
Now considering our class has a member function: display(). How do we call this function using a pointer? You know how:
p->display();
In the above example, I created a pointer myself, but in C++, an absolutely similar pointer like p is created automatically for every object of every class. That pointer is called the this pointer
The this pointer is local to the object. This means that it can be used meaningfully only inside the object i.e. in the code within the class definition. In order to understand the need for this pointer we have imagine the following scenario:
class A
{
      int x;
public:
      void func(A a)
      {}
}
The member function func() of the above class takes as an argument an object of the type A it self. This is indeed a rather bizarre situation. The function belongs to the class A and hence is defined inside of the class definition. This function is obviously allowed to access all the private, protected and public members of this class. So far so good. Here is how func() may use a member of the class inside it's body:
//assume we are still inside the class definition
void func(A a)
{
      cout<<x;
}
Notice how we use x without any specification to which x this is. This is because x does not require any additional specification at this point. There is only one x in the whole class definition and referring to x could only mean referring to that member. What if I told you that this is a short hand for a more detailed way of referring to x. Indeed there is a more detailed way of referring to a member of a class inside the class definition. This method includes the use of this pointer. This method is used to avoid any ambiguity that may arise over a member of the class. We would look into how such an ambiguity may arise in a bit but first check out how the detailed method works:
//assume we are still inside the class definition
void func(A a)
{
      cout<<this->x;
}
As I told you before, this pointer is nothing but a pointer to the object of the class. And so the syntax of referring to a member of the class using this pointer is the same as doing so using a normal pointer (with the arrow operator). What the cout statement in the above example means is that we wish to print the variable x which is a member of this very object of which this function is a member to. So that x will be printed which belongs to the object through which the function func() was invoked.
A obj1, obj2;
obj1.func(obj2); //will print x belonging to obj1
obj2.func(obj1); //will print x belonging to obj2


The detailed method described above is omitted mostly because it is required only when a foreign object (of the same type) is being used inside the class.

Remember how the this pointer is provided automatically for each object in C++. Well as it happens, the this pointer is also passed to every function of the class as a hidden parameter. You ask why? Well this is because in memory, when objects are created, space is given for only the non static members variables of the object. The member functions for each object are not placed separately in memory along with other things belonging to each object. Member functions are stored only once, with the class definition. And each object of the class uses these solitary definitions of member functions in turn. Then how do the member functions know which object it is this time which is calling them? I mean there doesn't seem to a way for the member functions to differentiate between each calling object unless an argument is passed (secretly) among other arguments to the member function, containing the identity (address) of the object calling for the services of the member function. Hence the this pointer is passed secretly behind our back by the compiler to every member function of the class (only to help us out). This is also the reason why this pointers can be used inside the body of a class definition only (body of the member functions).


Coming back to that ambiguity that I talked about before. When a member function of a class has an object of the same class as it's parameter, then this can lead to a confusion. Confusion on which object's member (the calling object or the parameter object) is being referred to at any point in the function body. When referring to some member (say x) of the calling object, use this->x and when referring to the member of the parameter object use objectName.x.



Such ambiguity can also arise when the member function takes a parameter with a name same to some member of the class. There too, this pointer can be used to save us and the compiler from all of the confusion.

class A
{
      int x;
public:
      void func(int x)
      {
            cout<<x;  //the parameter x
            cout<<this->x; //the member x
      }
}

Well, I have two parting thoughts:

1) Friend functions are not members of a class and therefore are not passed with a this pointer as a secret argument.
2) Static member functions also know nothing about this pointers. This is because static member functions are same for all objects. Objects don't get the luxury of having a personal static member function for themselves. So the whole issue of being able to recognize what object is calling a static member function goes down the drain.

No comments:

Post a Comment