8.8 — The hidden “this” pointer

One of the questions about classes that new object-oriented programmers often ask is, “When a member function is called, how does C++ keep track of 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 integer member variables for us.

Here’s a sample program that uses this class:

As you would expect, this program produces the result:


Somehow, when we call simple.setID(2);, C++ knows that function setID() should operate on object simple, and that m_id actually refers to simple.m_id. Let’s examine the mechanics behind how this works.

The hidden *this pointer

Take a look at the following line of code from the example above:

Although the call to function setID() looks like it only has one argument, it actually has two! When compiled, the compiler converts simple.setID(2); into the following:

Note that this is now just a standard function call, and the object simple (which was formerly an object prefix) is now passed by address as an argument to the function.

But that’s only half of the answer. Since the function call now has an added argument, the member function definition needs to be modified to accept (and use) this argument as a parameter. Consequently, the following member function:

is converted by the compiler into:

When the compiler compiles a normal member function, it implicitly adds a new parameter to the function named “this”. The this pointer is a hidden const pointer that holds the address of the object the member function was called on.

There’s just one more detail to take care of. Inside the member function, any class members (functions and variables) also need to be updated so they refer to the object the member function was called on. This is easily done by adding a “this->” prefix to each of them. Thus, in the body of function setID(),m_id (which is a class member variable) has been converted to this->m_id. Thus, when “this” points to the address of simple, this->m_id will resolve to simple.m_id.

Putting it all together:
1) When we call simple.setID(2), the compiler actually calls setID(&simple, 2).
2) Inside setID(), the “this” pointer holds the address of object simple.
3) Any member variables inside setID() are prefixed with “this->”. So when we say m_id = id, the compiler is actually executing this->m_id = id, which in this case updates simple.m_id to id.

The good news is that all of this happens automatically, and it doesn’t really matter whether you remember how it works or not. All you need to remember is that all normal member functions have a “this” pointer that refers to the object the function was called on.

“this” always points to the object being operated on

New programmers are sometimes confused about how many “this” pointers exist. Each member function has a “this” pointer parameter that is set to the address of the object being operated on. Consider:

Note that the “this” pointer alternately holds the address of object A or B depending on whether we’ve called a member function on object A or B.

Because “this” is just a function parameter, it doesn’t add any memory usage to your class (just to the member function call, since that parameter goes on the stack while the function is executing).

Explicitly referencing “this”

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

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

Note that our constructor is taking a parameter of the same name as a member variable. In this case, “data” refers to the parameter, and “this->data” 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!

Some developers prefer to explicitly add this-> to all class members. We recommend that you avoid doing so, as it tends to make your code less readable for little benefit. Using the m_ prefix is a more readable way to differentiate member variables from non-member (local) variables.

Recommendation: Do not add this-> to all uses of your class members. Only do so when you have a specific reason to.

Chaining member functions

Second, it can sometimes be useful to have a class member function return the object it was working with as a return value. The primary reason to do this is to allow a series of member functions to be “chained” together, so several member functions can be called on the same object! You’ve actually been doing this for a long time. Consider this common example where you’re outputting more than one bit of text using std::cout:

In this case, std::cout is an object, and operator<< is a member function that operates on that object. The compiler evaluates the above snippet like this:

First, operator<< uses std::cout and the string literal “Hello, ” to print “Hello, ” to the console. However, since this is part of an expression, operator<< also need to return a value (or void). If operator<< returned void, you’d end up with this:

which clearly doesn’t make any sense (and the compiler would throw an error). However, instead, operator<< returns *this, which in this context is just std::cout. That way, after the first operator<< has been evaluated, we get:

which then prints the user’s name.

In this way, we only need to specify the object (in this case, std::cout) once, and each function call passes it on to the next function to work with, allowing us to chain multiple commands together.

We can implement this kind of behavior ourselves. Consider the following class:

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

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

Note that add(), sub() and mult() are now returning *this. Consequently, this allows us to do the following:

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

First, calc.add(5) is called, which adds 5 to our m_value. add() then returns *this, which is a reference to calc. Our expression is now calc.sub(3).mult(4). calc.sub(3) subtracts 3 from m_value and returns calc. Our expression is now calc.mult(4). calc.mult(4) multiplies m_value by 4 and returns calc, which is then ignored. However, since each function modified calc as it was executed, calc’s m_value now contains the value (((0 + 5) - 3) * 4), which is 8.


The “this” pointer is a hidden parameter implicitly added to any non-static member function. Most of the time, you will not need to access it directly, but you can if needed. It’s worth noting that “this” is a const pointer -- you can change the value of the underlying object it points to, but you can not make it point to something else!

By having functions that would otherwise return void return *this instead, you can make those functions chainable. This is most often used when overloading operators for your classes (something we’ll talk about more in chapter 9).

8.9 -- Class code and header files
8.7 -- Destructors

137 comments to 8.8 — The hidden “this” pointer

  • Louis Cloete

    In the first sentence of the paragraph directly above "“this” always points to the object being operated on," you again use "transparently" where I think you should use "opaquely" or "hidden away from you as programmer."

  • Rashid

    int main()
        Simple A(1); // *this = &A inside the Simple constructor
        Simple B(2); // *this = &B inside the Simple constructor
        A.setID(3); // *this = &A inside member function setID
        B.setID(4); // *this = &B inside member function setID

        return 0;

    I am not sure how is *this = &A
    Because *this should contain actual object A by my understanding, I don't get why the value of this pointer contains an address. In my current understanding, I would say that this = &A. Can you please explain why I am wrong?

    • Rashid

      Hi Alex,
      I am not sure how is *this = &A
      Because *this should contain actual object A by my understanding, I don't get why the value of this pointer contains an address. In my current understanding, I would say that this = &A. Can you please explain why I am wrong?

    • Alex

      I agree, I'll update the lesson to remove the asterisk before "this".

  • Rahul Kumar

    Hi Alex, although I understood the logic here but seeing the term <Calc&> for the first time. Can you please explain this.

    • It's a reference. Lesson 6.11, 7.4a

      • Rahul Kumar

        But <&> keyword is used before the variable name in "reference" and not after it!

        • @Calc is not a variable, it's a type.

        • Arno Adam

          I'm not quite sure about this myself...
          As far as I understand it, "Calc&" is what defines what kind of datatype the function will return. In the unaltered example above it, the function just changed m_value and didn't return anything, so it was of type "void". In the example below, its intention is to return a pointer, correct? So why isn't it "Calc*" instead of "Calc&"?

          EDIT: I just read the sentence below that, where it says "[...]then returns *this, which is a reference to calc". So it's actually a reference instead of a pointer? I know they are pretty similar, but this implies that underneath the surface, they are handled exactly the same...

          • & applied to the right side of a type is a reference.
            & applied to the left side of a variable is a pointer.
            * applied to the right side of a type is a pointer.
            * applied to the left side of a pointer is a reference.

            Under the surface, pointers and references are the same.

  • Lan

    hi Alex

    the fraction don't reduce when i  enter 6 to m_numerator and 12 to m_denominator

  • vitrag shah

    first of all sorry, because I am not asking the doubt about this chapter

    I am doing a complex maths operation in that there I got an error :(
    error: expression cannot be used as a function

    I just want to know what that what this error mean?

  • Winston Lai


    I was wondering why to you return by reference for the member function. It is in consistent with the return type since we are returning *this, which is a pointer that points to the address of the object. I am confused, can you please clarify?

    • > *this, which is a pointer that points to the address of the object
      "*this" isn't the pointer, "this" is the pointer. It doesn't point to an address, it points to the object.
      "*this" gives us the object that "this" is pointing to.

      • Winston Lai

        Hi nascardriver, so wouldn't "this" be a object that is passed back to the caller by value? Also, if this is return by reference, since "this" pointer is a local pointer,  if we are dereferencing "this" to the get actual object before the function ends, then return as a reference, wouldn't the reference be gone since "this" is destroy be the end ot eh function? Thanks for your reply!!

        • > wouldn't "this" be a object
          > since "this" pointer is a local pointer
          You can't have both. @this is a pointer.

          > if we are dereferencing "this" to the get actual object before the function ends, then return as a reference, wouldn't the reference be gone
          No, @this points to the object the function is called on

  • Ishak

    Does std::cout return as *this or as *this-> ???

    • @std::cout doesn't return anything, it's an object, not a function.

      @std::cout.operator<< returns a reference to *this.

      std::ostream::operator<< -

  • Hi Alex!
    I see "The “this” pointer is a hidden parameter implicitly added to any member function" but I can't use "this" in static member function.
    Thank you!

    • nascardriver

      The nullPointer!

      The this-pointer points to the instance on which the function is called. Since static functions don't have an instance they're called on, there's no this-pointer.
      I understand your confusion, Alex' sentence might be better written as
      "The “this” pointer is a hidden parameter implicitly added to any non-static member function".

  • Laksh Singla

    Hi Alex, I had a few doubts wrt above piece of code. This does not work as expected, i.e calls chain and the first print value shows 0 + 19 - 7. But c only gets updated as per the first call i.e value of c.x after the first statement in main remains just 19. The only logical explanation that I was able to think of that returning *this created a new object and returned it on which subtract(7) ran and then a new object was again returned which printed 12. Therefore after the first statement, value remained just 19. Please could you explain this and correct me if I am wrong.
    Thank you

    • nascardriver

      Hi Laksh!

      You're returning by copying. See lesson 6.11, 6.11a, 7.3 and 7.4a, especially 7.4a.

  • Jagadeesh Takkalaki

    Alex, I have got confused with object creation with pointer.
    Below code Snippet supose to give error, But I am getting output as hello world.How actually it will work internally??
    Class A
        void foo()
         cout<<"Hello World\n";


    int main()
    A *a=NULL;
    a->foo(); //Here I geeting output Hello world
    return 0;

    • nascardriver

      Hi Jagadeesh!

      @foo is the same for every @A you instantiate so there will be only one @foo function for all objects. When you call @foo, @a will be passed to @foo (Your compiler adds a 'this' parameter to all member functions). Since @foo doesn't use the 'this' parameter there is no problem with calling @foo on a nullptr. If @foo were to access a run-time member of @A you'd get a crash.

      Please use code tags, uniform initialization, and nullptr.

  • Micah

    Right before the summary:
    "However, since each function modified calc as it was executed, calc’s m_value now contains the value ((0 + 5) - 3) * 4), which is 8."

    You're missing just one parenthesis in:
    ((0 + 5) - 3) * 4)

    Should be:
    (((0 + 5) - 3) * 4)

    Almost meaningless correction but I'll bet it'll bother you now that you know it's there :)

  • Dekasi

    Regarding this example:

    can we do something like this:

    It keeps saying that an identifier is expected.

  • Steve

    I remember encountering something like

    Does that has anything to do with the hidden this pointer?

    • Alex

      Yes, assuming you call this from within a member function, this would dynamically allocate a copy of the implicit object (via the copy constructor)

  • Matias

    With regards to the Simple (and *this remarks) of the first part of the tutorial:

    I've looked at the disassembly code to understand what actually goes on (reverse engineering ftw), specifically on the following line:

    This should be easier to examine since there's no istream/cout bloat code. I'll be referencing the following pictures:

    Picture A -> ASM code right before function call ->
    Picture B -> ASM code in Cheat Engine ->
    Picture C -> ASM code of function itself ->

    I guess it can be seen as "proof" as to what you've stated in the tutorial.

    Note: the compiler is automatically set to use the calling convention cdecl (unless i specify another convention, which we haven't done).
    Here's a link that explains calling conventions pretty well:
    Lets keep in mind that "Arguments are passed on the stack in Right-to-Left order" in the CDECL calling convention.

    (Picture A / B)
    Let's start by examining the instructions on the function ASM code line by line:
    1) push 2 -> we've called setID() with an int argument of 2. (this is our rightmost argument)

    2) lea ecx, [simple] -> the brackets around "simple" work like the dereference operator * in c++ (after all, it is the "this" pointer we're talking about). We're assigning the value stored in this pointer (the simple object) into the ecx register, which we'll use as an argument to our function. (our leftmost argument)

    3) call Simple::setID (0CF3355 - main.exe + 3355). Keep in mind we've only passed one argument into the function ourselves. But under the hood, there's two things being passed: the address of the object we're dealing with, and the value of the id we want to assign to that object. The function call, in ASM, effectively translates to:

    As Alex stated in the tutorial.

    Furthermore, if we look at the function code itself for setID() - Picture C:

    (will be corrected in a reply) ..

    So we can see through looking "under the hood" that the compiler does indeed treat:


    Hopefully this isn't too confusing and it makes some sense. I posted this to sort of "reinforce" the concept of how the compiler actually goes about the task. I do admit that the way you explained it was easier for everyone to understand, but I thought I'd share this for people that want to see how it actually happens, sort of as being shown a mathematical proof to a concept :P

    Anyways, enjoying the content as always. Keep it up!

    • Matias

      With respect to the function itself:

      - Preparing stack frame

      -> address of member m_iID is in the ecx register
      -> move the address of the member into the this pointer (dereferencing the pointer now leads to the int value)
      -> move the id argument we passed in into the ecx register
      -> move our value of id (in ecx) into the value of eax (the member variable) = this essentially is where the assignment happens

      - Exiting stack frame, return back to main

      Sorry for making this a bit confusing but ASM is a bit hard to explain in words :P

      EDIT: Special note:

      on the assignment line, which is essentially:

      EAX here is indeed the pointer to a Simple object (its first element). Since our Simple class only has one member, this line is just simply how it is there, with no offset to the eax register.

      If we added a second member, say an int, the line to replace that second element would be:

      The [eax+0x4] is a dereference to the second member, and by moving ecx's contents (the argument we passed in to setID()) we are effectively changing its value.

  • Ben

        setID(&simple, 2); // note that simple has been changed from an object prefix to a function argument!
    Note that this is now just a standard function call, and the object simple (which was formerly an object prefix) is now passed by address as an argument to the function.

    Don't you mean "is now passed by reference"? Or is the ampersand intended to be used in the "address of" context here. Definitely can be confusing.

    Thanks for the great tutorial!

    • Alex

      It's passed by address, and the ampersand in this context means "address-of".

      Yes, it's confusing, as the context of the ampersand varies depending on where it's used. :( I wish they'd used a different symbol.


    Isn't it more appropriate to call it "Chaining Function Calls" rather than "Chaining Objects?" because that's not what really happens.

    • Alex

      Well, it kind of does, as the object is chained from the output of one function into the input of another function. But I agree, calling it "Chaining Member Functions" is a clearer. Thanks for the feedback.

  • can you explain why did this code gave me "2" as output?

    using namespace std;
    class set
        int m_i;
            m_i = 0;
        set add(int i)
            m_i += i;
            return *this;
        int  getval()
            return m_i;
    int main()
        set s;

    • Tuan

      The method "add" didn't return reference to set object, then output should be 2.

    • Alex

      Yes. Because add() is returning a set by value, which makes a copy. So when you call s.add(2), 2 is added to s, and then a copy of that s+2 is returned. So when the second .add(2) is executed, it's executed on the copy, not the original.

      To fix this, add() should return set by reference, not by value.

  • Seth_the_coder

    Hi Alex,
    My name is Seth Mwebi from Kenya. I have been following your tutorials for over seven months now. Back then I knew nothing about programming but now I feel like am ready to go pro:). Thanks for the effort you put in maintaining this tutorial.


      Same here bro, Been following along with this tutorial since June. This has helped me so much. Right now, I'm in a course that requires a good knowledge of C++. I've tried many other online courses: Lynda, Udemy, and other online sources, but none of them felt right and they made me quit after like a day.However, due to this website, I am surviving through it. Thanks

  • sabbir hasan

    Calc &add(int value){m_value+=value;return *this;}

    IN THIS SEGMENT..why you use Calc &add.why you use class here?

    i'm not good at i can't understand it.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]