Search

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:

2

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 transparently to you as a programmer, 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!

Chaining objects

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 functions to be “chained” together, so several 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.

Summary

The “this” pointer is a hidden parameter implicitly added to any 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
Index
8.7 -- Destructors

72 comments to 8.8 — 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:

      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 ?

    [code]
    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:

      • 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!

        • Alex

          When the compiler compliles the class, it will see the function SetID(int), and compile it. When it compiles it, it will generate a new name for the function’s name that includes the class name as well as any parameters (but not the return type). In this way, it should generate a unique name that doesn’t collide with any other functions.

          When we call simple.setID(2), it does the same name mangling procedure, and sees if it matches with the function it generated from the class. They should match.

    • 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?

      • Alex

        The function in the class definition is also modified to add an additional parameter. So although we declare SetID(int), the compiler compiles it as SetID(Simple*, int).

        Thus, the declaration and call match in the number of parameters.

  • 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 :

    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).

      • Alex

        A nitpick: it’s not a memory leak (no dynamic memory is being lost). The copies of Calc will be cleaned up when the expression finishes executing. However, the rest of your analysis is correct.

        • Chris

          but if i doing this

          it’s work! the output is 8! how it can be happen? i think the functions is still return a new copy of the class so i think it wouldn’t work.

          • Alex

            In the case above, we start with calc=0. add(5) operates on calc, so calc now has value 5 and a copy is returned. sub(3) happens on the copy, producing value 2, which is returned in another copy. mult(8) happens on that copy, producing value 16, which then gets printed.

            But note calc() only has value 5 because sub(3) and mult(8) operated on copies.

  • Rami

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

    br,

    • Alex

      The “this” pointer was added into C++ before the language supported references. That’s the only reason.

      It would definitely make more sense if “this” were a reference, since it would be easier to use and it’s always initialized to something.

  • priyesh lakar

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

    • Alex

      I’m not quite sure what you mean. Each member function contains only one this pointer regardless of the number of parameters, and regardless of the number of objects of that class that have been instantiated.

      If you were to do something like this:

  • 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!

  • 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() ;

  • nice meme

    cant wrap my head around this:

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

    can someone pls baby step me through this.

    • Pavan Shetty

      @nice meme

      when it gets called,

      it receives an integer value and then  adds the value with ‘m_nvalue and stores it in m_nValue and returns the address of that object (cCalc in this case) as the reference.

      P.S: ‘pls do correct if there is any mistakes..’

    • Alex

      If this function returned a void instead of Calc&, you’d probably think the function was trivial, right?

      All we’ve done is have the function return a reference to the object it was called on.

      So if we call simple.Add(4), the function will add 4 to m_nValue and then return a reference to object simple. What you do with that reference is up to you. 🙂

  • Connor

    Hello again Alex.
    in the top-most code:

    why doesn’t the compiler complain that we are attempting to use SetId() function before it’s officially declared as a void function?
    Thanks again for this all these epic lessons :).

    • Alex

      Good question. Function definitions within the class body are treated as if they were actually defined after the class had been defined. This means by the time the compiler gets around to compiling the body of the constructor, it’s already seen the definition for SetID().

      • PolarPause

        I’m a little confused. Do you mean to say that the compiler first declares all class functions (including constructors) before defining any of them? Do you mean "This means by the time the compiler gets around to compiling the body of the constructor, it’s already seen the" declaration for SetID()?

        So in a way, the code is like:

  • Shivam Tripathi

    hii…alex..one confusion regarding the "this" pointer…

    The type of "this" pointer is "class-name* const this"…here ‘const’ specifies that the particular pointer will point to a particular ‘object’ only which we’ll declare later…Now when we’ll call a member function on a particular object ..C++ implicitly passes an extra argument in the member function parameter list as"the address of that object"…and thus the function’s prototype and definition also get’s changed implicitly…

    Now my question is that "this" pointer is a unique aspect of C++…and also we know that we can have a lot of objects of a same class-type…so how this unique pointer which is also declared as "const" ..can point to such a lot objects…coz every objects of a class have their own instance variables…so how this "this" pointer which is also a "const" can point to such a large number of objects simultaneously…
    plz help me out..

    • Alex

      As you’ve noted, the “this” pointer is a hidden parameter that gets added onto every non-static member function, right? Just like a normal function parameter, the this pointer has function scope.

      When a member function is called, the compiler ensures that the address of the object whose member function is being called is passed in as the argument to the this pointer. This happens transparently.

      So the this pointer doesn’t point to a large number of objects simultaneously -- it exists as a function parameter only when a member function is being called.

      • Shivam Tripathi

        So it means that if we have 2-3 objects of the same class and if we call a non-static member function on all these 2-3 objects..then it wouldn’t contradict the "const" behavior of the "this" pointer..coz every class objects will have their own instance of class’s field….and also we know that function parameters are only confined to that particular function…it’s nothing to do with other member function parameters…

        So ..every function have their own "this" pointers as their parameter which will contain the address of that particular object on which it’s being called upon…
        Am i ryt???

  • Manohar

    Hi Alex,

    I have a question. When we use POSTMESSAGE OR SENDMESSAGE which will eventually call the message handlers. How is the this pointer passed in such cases? How is this preserved during the message handling process? How does the handler gets the this pointer? Can you please elaborate so that it would be helpful to understand.

    Thanks in advance.

  • Mr D

    Hi Alex,

    I’m a little confused (hey, what’s new?!) by the first example in this lesson.

    What’s wrong with a simpler version like this?:

    I know you answered this in your earlier reply to a post, but i don’t think you explained the reason for making it more complicated then in the example from lesson 8.5!

    • Alex

      This “simpler” version of the class you’ve provided removes useful functionality. The constructor allows us to set the value of m_nID when the object is initialized, but there’s no way to change it afterward.

      Thus, this line of the example wouldn’t work:

      Having the constructor use SetID() instead of setting the value directly was just a convenient way to reduce redundant code.

  • Len

    This could be really useful, but I cannot figure out how to get this to work when split into a header/cpp file.  (I am trying to practice keeping my code organized!).

    For instance I created a "CascadedFunctions" class and stored it in header and cpp files.  The only way I could get it to work is if I use a function at the end that just returns the value.  (using Codeblocks 13.12, gcc)  Here is a snippit:

    the cpp file:

    This code calls the function:

    This does output "124" as expected, but without the terminating "GetValue" function this will not compile.  What am I doing wrong?

    • Alex

      Your Add() and Sub() function returns a CascadedFunctions object. std::cout doesn’t know how to output one of those. By calling GetValue(), you’re having your CascadedFunctions object return an integer, which std::cout does know how to output.

      If you want to be able to output a CascadedFunctions object directly without having to call GetValue(), the best way would be to override operator<<. I show how to do that in lesson 9.3

      • Len

        OK, thank you Alex.
        BTW, this tutorial is fantastic.  The only problem I was having was retaining everything I learned through all the lessons - I needed some relatively big, complex projects, so I signed up for a Coursera course (Crypto) so I could cement in my head the lessons learned through section 7.  This is starting to pay off in a big way, and now much of what you taught me from lessons 0 through 7 come more naturally to me.

        If you are thinking of publishing this tutorial you might want to consider some big projects at two or three stages along the way (midterms and a final?).  After section 7 people should have enough skills to program large projects, and after section 8 you could instruct people to put all their code from section 7 into classes and those classes into header files and libraries.

        Just a thought.

  • Reaversword

    Why chaining isn’t working here?

    • Alex

      Your program is broken for many reasons, but there are two things that stand out as problematic:
      1) You don’t specify what unit dataContent is in. Does dataContent represent seconds, minutes, hours, days, or months? Who knows.
      2) In my example, each of the functions modifies the internal result. In your example, your functions are dependent on each other (that is, the input of toMonths() is dependent on the output of toDays()). When this is the case, it’s usually better to use nested function calls than chained function calls.

      • Reaversword

        Appears the problem is in the function calls order. The four calls to "Obj.getDc()", the same ones acting as arguments for the chained functions, was the first thing it was happening, so this:

        Was exactly like this:

        Easier to see adding in getDc function a message.

        It works in this way:

        And yes, you’re right, there is broken for many reasons, dataContent is just an auxiliar value. It was just about a quick exercise to get chaining working.

  • Baubas

    What is Calc? Constructor?

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

  • Kodnot

    From "Chaining objects":
    "In this way, we only need to specify the object (std::cin) once, and each function call passes it on to the next function to work with, allowing us to chain multiple commands together." Shouldn’t this be "specify the object (std::cout) once…"? Because the examples and explanations given before this sentence were about std::cout, not std::cin ^^

  • Lokesh

    In chaining objects section,
    "In this case, std::cout is an object, and operator>> is a member function that operates on that object."
    should be
    "In this case, std::cout is an object, and operator << is a member function that operates on that object."
    (operator)

  • Shiva

    Typos:

    > As you’re expect… (you would)
    > calc now contains the value… (technically, calc’s member m_value contains ‘the value’)

    Some of the recent concepts has been real tricky; need to do some real workout to let them soak in. I hope quizzes are coming soon.

    Thanks for the nice lesson, Alex. 🙂

  • Darren

    I was once told an analogy for objects which has stuck:

    You walk into a restaurant. Sitting down you notice that the diner at table seven has a juicy, rare steak (probably rib-eye). You say to the waiter "I’ll have what their having" pointing at table number seven. Now do you mean for the waiter to go to table seven, pick up the other diner’s dish and bring it over to you, or for the waiter to go to the kitchen and tell the chef your order so they can cook you a steak of your own. Unless you’re a sociopath, its probably the latter. Once your order arrives you can proudly claim that "This is my steak. There are many others like it, but this steak is mine!". The diner at table seven could make the same claim of their steak, but are more probably eyeing the exit door for a quick escape from the nutter that walked in a few minutes ago.

  • Robin

    Hi, I found an inconsistency toward the end of the "<strong>The hidden *this pointer</strong>" section where you wrote "<strong>simple->m_id</strong>" instead of "<strong>simple.m_id</strong>". I don’t believe simple is a pointer.

    Thus, when *this points to the address of simple, this->m_id will resolve to <strong>simple.m_id</strong>.

    So when we say m_id = id, the compiler is actually executing this->m_id = id, which in this case updates <strong>simple->m_id</strong> to id.

  • Rob G.

    Why doesn’t (->) work with some instantiated objects not not with (.) and vice versa?

    e.g.:

    (can’t use ->);

    on the heap:

    (can’t use . operator)

    1.Is the (this->) for member selection related to ("this") (holding the object address) and how
    2. (->) is syntactically correct for a->b, (*a).b I can’t find an example of (a*).b: can you post a simple example?

    • Alex

      a->b is the equivalent of (*a).b

      Since you can’t dereference a non-pointer value, a->b won’t work if a isn’t a pointer.

      You typically use . with non-pointers, and -> with pointers.

  • Rob G.

    I answered my own question (#2) below. Please consider answering my 1st one and (.) ver5sus (->) : )
    Alex here is an example of how a->b is converted from (a*).b. (*ptr).foo() below.I would still appreciate answers to the (->) and (.) operators as above.

    Also I wanted to say that I don’t know if its me but in the interest of improving the site, you must know I learned about 90% of this topic researching outside of the lesson. Maybe its just me.

    • Alex

      I covered the difference between operator. and operator-> in lesson 6.12. Is there something that made you think the contents of that lesson wasn’t applicable to this one? Unclear if I’m missing something or whether it’s just you. 😛

  • Rob G.

    I’ll walk the comment back. I expected a quick easy read but I am going to have to spend more time picking through it. Its all there. So its me not you-classic breakup line : )

  • Gapo

    I made a mistake and realised that without "return *this", the output is still correct

    So what I am trying to say is that this works just as the example above

    Do I still need to return *this in the future ?

    • Alex

      It’s up to you, depending on whether you want to make the functions chainable or not.

      • Gapo

        What I ment is that the function is chainable in both ways , even if I write it like :

        That got me a little bit confused

        • Alex

          Well, that makes two of us confused then. When I remove the “return *this” part of those functions, Visual Studio 2015 gives me compile error, indicating that the functions must return a value (as I would expect). So not sure why you’re experiencing something different.

          • Gapo

            I will just keep doing it with "return *this" since this is the crrect way, thanks anyways Alex.
            btw I am using Code::Blocks , maybe something is wrong with it , every now and then I do not get recommendations when writing my code , so I need to restart the program for it to work again.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter