Navigation



8.7 — The hidden “this” pointer

One of the big questions that new programmers often ask is, “When a member function is called, how does C++ know which object it was called on?”. The answer is that C++ utilizes a hidden pointer named “this”! Let’s take a look at “this” in more detail.

The following is a simple class that holds an integer and provides a constructor and access functions. Note that no destructor is needed because C++ can clean up integers for us.

class Simple
{
private:
    int m_nID;

public:
    Simple(int nID)
    {
        SetID(nID);
    }

    void SetID(int nID) { m_nID = nID; }
    int GetID() { return m_nID; }
};

Here’s a sample program that uses this class:

int main()
{
    Simple cSimple(1);
    cSimple.SetID(2);
    std::cout << cSimple.GetID() << std::endl;
}

Let’s take a closer look at the following line: cSimple.SetID(2);. Although it looks like this function only has one parameter, it actually has two! When you call cSimple.SetID(2);, C++ internally converts this to SetID(&cSimple, 2);. Note that this is just a normal function call where C++ has added a parameter, and automatically passed in the address of the class object!

Since C++ converts the function call, it also needs to convert the function itself. It does so like this:

    void SetID(int nID) { m_nID = nID; }

becomes:

    void SetID(Simple* const this, int nID) { this->m_nID = nID; }

C++ has added a new parameter to the function. The added parameter is a pointer to the class object the class function is working with, and it is always named “this”. The this pointer is a hidden pointer inside every class member function that points to the class object the member function is working with.

Note that m_nID (which is a class member variable) has been converted to this->m_nID. Since “this” is currently pointing to cSimple, this actually resolves to cSimple->m_nID, which is exactly what we wanted!

Most of the time, you never need to explicitly reference the “this” pointer. However, there are a few occasions where it can be useful:

1) If you have a constructor (or member function) that has a parameter of the same name as a member variable, you can disambiguate them by using “this”:

class Something
{
private:
    int nData;

public:
    Something(int nData)
    {
        this->nData = nData;
    }
};

Note that our constructor is taking a parameter of the same name as a member variable. In this case, “nData” refers to the parameter, and “this->nData” refers to the member variable. Although this is acceptable coding practice, we find using the “m_” prefix on all member variable names provides a better solution by preventing duplicate names altogether!

2) Occasionally it can be useful to have a function return the object it was working with. Returning *this will return a reference to the object that was implicitly passed to the function by C++.

One use for this feature is that it allows a series of functions to be “chained” together, so that the output of one function becomes the input of another function! The following is somewhat more advanced and can be considered optional material at this point.

Consider the following class:

class Calc
{
private:
    int m_nValue;

public:
    Calc() { m_nValue = 0; }

    void Add(int nValue) { m_nValue += nValue; }
    void Sub(int nValue) { m_nValue -= nValue; }
    void Mult(int nValue) { m_nValue *= nValue; }

    int GetValue() { return m_nValue; }
};

If you wanted to add 5, subtract 3, and multiply by 4, you’d have to do this:

Calc cCalc;
cCalc.Add(5);
cCalc.Sub(3);
cCalc.Mult(4);

However, if we make each function return *this, we can chain the calls together. Here is the new version of Calc with “chainable” functions:

class Calc
{
private:
    int m_nValue;

public:
    Calc() { m_nValue = 0; }

    Calc& Add(int nValue) { m_nValue += nValue; return *this; }
    Calc& Sub(int nValue) { m_nValue -= nValue; return *this; }
    Calc& Mult(int nValue) { m_nValue *= nValue; return *this; }

    int GetValue() { return m_nValue; }
};

Note that Add(), Sub() and Mult() are now returning *this, which is a reference to the class itself. Consequently, this allows us to do the following:

Calc cCalc;
cCalc.Add(5).Sub(3).Mult(4);

We have effectively condensed three lines into one expression! Let’s take a closer look at how this works.

First, cCalc.Add(5) is called, which adds 5 to our m_nValue. Add() then returns *this, which is a reference to cCalc. Our expression is now cCalc.Sub(3).Mult(4). cCalc.Sub(3) subtracts 3 from m_nValue and returns cCalc. Our expression is now cCalc.Mult(4). cCalc.Mult(4) multiplies m_nValue by 4 and returns cCalc, which is then ignored. However, since each function modified cCalc as it was executed, cCalc now contains the value ((0 + 5) – 3) * 4), which is 8.

Although this is a pretty contrived example, chaining functions in such a manner is common with String classes. For example, it is possible to overload the + operator to do a string append. If the + operator returns *this, then it becomes possible to write expressions like:

cMyString = "Hello " + strMyName + " welcome to " + strProgramName + ".";

And it is pretty easy to see the benefit in being able to do that! We will cover overloading the + operator (and other operators) in a future lesson.

The important point to take away from this lesson is that the “this” pointer is a hidden parameter of any member function. Most of the time, you will not need to access it directly. It’s worth noting that “this” is a const pointer — you can change the value of the object it points to, but you can not make it point to something else!

8.8 — Constructors (Part II)
Index
8.6 — Destructors

34 comments to 8.7 — The hidden “this” pointer

  • Zafer

    As a pointer, “this” contains the memory address of a class object. However, since we can call a class function from different objects, “this” pointer should be able to contain different addresses so that it can point to different objects. How does this happen when “this” is a const pointer?

    • As you note, the “this” pointer can contain different addresses so it can point to different objects. This does not violate the fact that the *this pointer is const. All the const means is that we can not change what the *this pointer points to when we’re inside the function. The const does not restrict what we set the pointer to in the first place!

      For example, consider the following function:

      int PrintValue(const int nValue)
      {
          // We can not change the value of nValue inside the function!
          cout < < nValue;
      }
      
      int main()
      {
          // However, we can set nValue to whatever we want
          // when we call the function!
          PrintValue(4);
          PrintValue(6);
      }
      

      This program is pretty straightforward. The first time we call PrintValue, we set nValue to 4. The second time we set it to 6.

      The *this pointer works exactly like this, except that it's type is "X* const" instead of int (where X is the name of the class the non-static member function belongs to), and the compiler automatically sets it's value based on the object we're calling the function on.

  • emre

    I tried this but didn’t work , why ?

    int main()
    {
        Simple cSimple(1);
        SetID(&cSimple,2);
        std::cout << cSimple.GetID() << std::endl;
    }
    • I don’t see anything syntactically wrong with that program, so without knowing what the error message was, I can’t say. It is bizarre that you seem to have SetID() declared as a non-member function. Really it would be better if SetID() were declared as a member function, and then you could just say:

      cSimple.SetID(2);
      
      • yakisobskie

        “When you call cSimple.SetID(2);, C++ internally converts this to SetID(&cSimple, 2);”

        “SetID(&cSimple, 2)” <- normal function call

        how does the program knows that the function we are calling "SetID(Simple*, int)" is within "Simple", since it is not declared in the main loop but inside "Simple"? Thanks!

    • renju

      In the class defenition if it give SetID(int) and in the main funtion SetID called with two parameters(&cSimple,int). How it will work?

  • [...] 2007 Prev/Next Posts « 8.5 — Constructors | Home | 8.7 — The hidden “this” pointer » Thursday, September 6th, 2007 at 9:14 [...]

  • Daniel

    Hi there,

    If you CAN change the object that ‘this’ points to, but you CAN’T change the ‘this’ pointer itself, shouldn’t the parameter specification read:

    Simple *const this

    instead of

    const Simple *this

    ?

    Daniel.

  • cammy

    I have been doing quite well in these tutorials (Their great) but I have had one big problem:

    Is there a way to pause a program at a certain place until the user does something?
    For example:

    #include <iostream>
    
    int main()
    {
         using namespace std;
         cout << "Hello World! << endl;
         return 0;
    }

    This will flash up “Hello World” for an instant and then close. I know that in Windows DOS, there is the ‘pause’ command. Is there a command that has a similar function in C++?

  • FuturePixstar

    You finished this with “this” is a constant pointer, if that is so is it possible then to access variables though “this” in the same fashion as you would use a const pointer used to access a variable its pointing to in a function to garentee that the value cannot be changed… I know i could just try this myself but I just wanted to share an idea with the readers :)

  • Ahmed

    Hi Alex,

    First of all I want to thank you for this great tutorial..It helped me a lot..
    I just have a small problem..
    When I compiled this :

    #include "stdafx.h"
    #include <iostream>
    
    class Calc
    {
    private:
        int m_nValue;
    
    public:
        Calc() { m_nValue = 0; }
    
        Calc& Add(int nValue) { m_nValue += nValue; return *this; }
        Calc& Sub(int nValue) { m_nValue -= nValue; return *this; }
        Calc& Mult(int nValue) { m_nValue *= nValue; return *this; }
    
        int GetValue() { return m_nValue; }
    };
    
    int main()
    {
        using namespace std;
        Calc cCalc;
        cCalc.Add(5).Sub(3).Mult(4);
        cout<<cCalc.GetValue()<<endl;
        return 0;
    }
    

    It printed 8 on the screen..but when I removed the & from “Calc& Add”, “Calc& Sub” and “Calc& Mult”..It printed 5 on the screen instead..
    I know that “Calc&” is a return by reference and that “Calc” is a return by value..Also, isn’t “this” supposed to be a pointer not a reference..
    I really don’t get that..Could you please explain it for me ?
    Thanx in advance…

    Ahmed

    • Maybe you want this :
      Calc * Add(int nValue) {
      m_nValue += nValue;
      return this;
      }

      cCalc.Add(5)->Sub(3).Mult(4);

      It’s just the differences between pointer and reference.

    • Maverick95

      Ahmed, in lesson 7.4a, Alex stated, “When a value is returned by value, a copy of that value is returned to the caller.”. Because you removed the & symbol from the return variable types, the function is now returning by value, which means it returns a NEW COPY of the class instance, not the original class instance itself! So the only function that operates on the instance cCalc is the first one, Add(5) – this will update m_nValue to 5, which explains the value that is printed. The other two functions, Sub(3) and Mult(4) are operating on copies of the original cCalc.

      I’m still inexperienced in C++, but the code you’ve presented above looks like an example of a memory leak. You’ve basically created three instances of the class Calc, but can only reference one of them, cCalc, in your code. This means that the other two must exist in memory, but you can’t reference them because they’ve been created indirectly (and unintentionally).

  • STUPID qustion

    why does Calc& Add() work and &Calc Add() does not????

    Is it the same as Calc &Add() ??????

  • AH! Got it!!! Sorry ignore me!!!

  • Rami

    is there any reason why this pointer is not implemented as a reference instead of a pointer?

    br,

  • [...] 8.7 The hidden “this” pointer [...]

  • abcd

    “…this actually resolves to cSimple->m_nID, which is exactly…”
    Should not this be cSimple.m_nID?

    cSimple is just an object, not a pointer to the class, so cSimple-> would try to go to the address stored in that location, instead of using the m_nID stored in that particular address space?

    Please correct me, if I am wrong.

  • priyesh lakar

    if there are 4 objects then how many this pointer will be created?

  • j.howard

    Hi,

    Could anyone clarify the following for me based on the below code:

    Calc& Add(int nValue) { m_nValue += nValue; return *this; }

    My thinking is: The function returns an address to a Calc object, the this pointer is a constant pointer that points to the memory address of the object Calc, by this I mean:

    std::cout << this; //prints the memory address of the object
    std::cout << *this; //prints out the value stored at memory address this

    So my question is really, why return *this and not return this.

    Also why is the amphersand after the Calc and not before as in Calc(amp here) not (amp here)Calc when stating the reurn type.

    Any help understanding this would be much appreciated.

    Thanks

    • j.howard

      Okay, for anyone who may be having a similar problem I have come up with (at least half of) the answer.

      The first issue with my thought process was that the function returns an address to the Calc object. It does not. The function Calc& Add(int); returns a reference to a Calc object…oops!

      this holds the address of the object that called Add. So it makes sense that the function would return *this as it is dereferencing the calling object. In other words it is returning the object itself not the address.

      So what’s happening is: A Calc object is made, it calls Add(...) and Add returns a reference to the object that called it. In other words it returns something (a reference) that accesses the actual object that called it (rather than a copy). As the returned value can be used as though it is the object that called it (that’s all a reference really is, just another variable to access the same memory location) it can make a call to the next function as though it were the object itself. Hence the chaining working.

      So to reiterate, it is a reference to the object that is returned NOT the address of the object. Returning the address could be made to work but you would have to use the -> operator and pointers instead of the . operator and references(or something like that).

      Lastly the amphersand is after the return type because that is just the grammar of C++ for returning by reference. Silly question really!

  • sidd.rane@gmail.com

    I would like to comment on ampersand after return type.

    returning *this is used to achieve function chaining i.e. we want to call functions on the same objects.
    for ex. if you check operator overloading of << insertion operator it return input reference again

    ostream& operator<< (ostream &out, Point &cPoint)
    {

    out << "(" << cPoint.m_dX << ", " <<
    cPoint.m_dY << ", " <<
    cPoint.m_dZ << ")";
    return out;
    }
    cout << pointobj1 << pointobj2;

    so function call goes like this
    1)cout.operator <<(pointobj1);// in operator << we are returning reference of cout
    //that is used for calling << 2nd time
    2)cout.operator <<(pointobj2);

    ###########################################3
    In your code after removing & from return type from Add, Mul, Sub etc.
    return type is temporary object.

    your code:
    cCalc.Add(5).Sub(3).Mult(4);
    cout<<cCalc.GetValue(); gives you 5 instead of 8.
    so in short you need to ensure all functions should be called on same cCalc object. you have to return it by reference and not by value.

    I hope it helps…
    Regards.

  • MrFinn

    Returning ‘*this’ from the member fuctions means that you are dereferencing the object itself from the objects address ‘this’. The return type from the member functions is reference type to access the actually returned object. If you want to use pointers and return ‘this’ from the member functions instead of ‘*this’ you could do it like below. Note the object instantiated in the heap with ‘new’ and then deleted:

    #include “stdafx.h”
    #include

    class Calc
    {
    private:
    int m_nValue;

    public:
    Calc() { m_nValue = 0; }

    Calc* Add(int nValue) { m_nValue += nValue; return this; }
    Calc* Sub(int nValue) { m_nValue -= nValue; return this; }
    Calc* Mult(int nValue) { m_nValue *= nValue; return this; }

    int GetValue() { return m_nValue; }

    };

    int main()
    {
    using namespace std;
    Calc *cCalc= new Calc;

    cCalc->Add(5)->Sub(3)->Mult(4);
    cout<GetValue()<<endl;

    delete cCalc;

    system("pause");

    return 0;
    }

  • MrFinn

    Darn, this page has some serious issues, it won’t let me fix the line and eats some characters. The line should be, cout, then <<, then member access operator from object ptr pointing to GetValue() and then <<endl;

  • Hesham

    Bravo, I see Good Work here!

  • rajeshsingh

    Call like this if you want to get proper value using call by value

    cout << cCalc.Add(5).Sub(3).Mult(4).GetValue() ;

  • [...] version of operator- doesn’t take any parameters! Where did the parameter go? In the lesson on the hidden this pointer, you learned that a member function has an implicit *this pointer which always points to the class [...]

You must be logged in to post a comment.