Skip to main content

C++ OOP

this Pointer

Complete lesson for this Pointer using LEARNCODEGURU’s 6-level learning model — from basics to advanced practice, with C++ OOP and STL where relevant.

L1

Basics — this Pointer

Section: C++ OOP. C++ this pointer — current object, name disambiguation, method chaining, and const this.

What is the this pointer?

  • this is an **implicit pointer** available inside **non-static** member functions.
  • It points to the **object** on which the member function was called.
  • Type (roughly): ClassName* const this for a non-const method — pointer to the current object.
  • You rarely declare it yourself; the compiler passes it for you.
  • **Real-life:** when you say “my phone,” *my* means the phone you are holding — this is that “my”.
  • **Real-life:** a remote is aimed at *this* TV — the member function operates on that TV object.
IdeaMeaningExample
thisAddress of current objectInside obj.f(), this == &obj
this->memberAccess member via thisthis->n = 10;
*thisThe object itself (lvalue)return *this;
Static methodsNo thisCannot use this in static functions
#include <iostream>
using namespace std;

class Box {
private:
    int side;
public:
    Box(int s) { this->side = s; }
    void show() const {
        cout << "side = " << this->side << "\n";
    }
};

int main() {
    Box b(5);
    b.show(); // inside show, this points to b
    return 0;
}

Why do we need this?

  • **Disambiguate** parameter names that match member names.
  • **Return the current object** for fluent / chained calls (obj.setX(1).setY(2)).
  • Pass the current object to other functions (other.attach(this)).
  • Compare identity: if (this == &other).
NeedWithout clarityWith this
Same namesn = n; ambiguous / wrongthis->n = n;
ChainingSeparate statements onlyreturn *this;
Identity checkHarderif (this == &obj)
CallbacksPass object somehowPass this

Resolving name conflicts (shadowing)

  • If a parameter has the same name as a data member, the parameter **hides** the member.
  • Use this->member = parameter; to assign into the object.
  • **Real-life:** form field “name” and argument “name” — you must say *this form’s name*.
#include <iostream>
#include <string>
using namespace std;

class Student {
private:
    int roll;
    string name;
public:
    void set(int roll, string name) {
        this->roll = roll;   // member = parameter
        this->name = name;
    }
    void show() const {
        cout << this->roll << " " << this->name << "\n";
    }
};

int main() {
    Student s;
    s.set(101, "Asha");
    s.show();
    return 0;
}

Returning *this — method chaining

  • Return type Class& and return *this; lets callers chain calls on the same object.
  • Common in builders / fluent setters: p.setX(1).setY(2).show();
  • **Real-life:** ATM menu steps on *this* account — deposit then show balance in one flow.
#include <iostream>
using namespace std;

class Counter {
private:
    int n = 0;
public:
    Counter& add(int x) {
        this->n += x;
        return *this; // enable chaining
    }
    Counter& reset() {
        this->n = 0;
        return *this;
    }
    void show() const { cout << n << "\n"; }
};

int main() {
    Counter c;
    c.add(5).add(3).show(); // 8
    c.reset().add(1).show(); // 1
    return 0;
}

this is not available in static members

  • static member functions have **no object** — therefore **no this**.
  • They can only use static data / other static functions (unless given an object explicitly).
  • **Real-life:** a classroom rule poster (static) is not tied to one student’s desk (this).
class Demo {
    int x;
    static int count;
public:
    void set(int v) { this->x = v; } // OK
    static void bump() {
        count++;
        // this->x = 1; // ERROR — no this
    }
};

Accessing members: this-> vs bare name

  • Inside the class, n and this->n usually mean the same member.
  • Use this-> when it improves clarity or when a name is shadowed.
  • Both obj.f() calls pass &obj as the hidden this argument.
class Point {
    int x = 0, y = 0;
public:
    void move(int dx, int dy) {
        x += dx;         // same as this->x
        this->y += dy;   // explicit
    }
};

Passing this to other functions

  • Sometimes another object needs a pointer/reference to the current one.
  • Example: a Button registers itself with a Window via window.add(this).
  • Be careful about lifetimes — do not keep this after the object is destroyed.
class Player;

class Team {
public:
    void add(Player* p); // stores non-owning pointer
};

class Player {
public:
    void join(Team& t) {
        t.add(this); // register current player
    }
};

Characteristics of this (summary table)

  • Keep these rules in mind when reading member functions.
PointDetail
ImplicitCompiler provides it; you do not declare the parameter
Points toThe object used to call the member function
In non-const methodType is like Class* (modifiable object)
In const methodType is like const Class* (read-only object)
Static methodsthis does not exist
Can return*this for references; this for pointers
Cannot reseatthis is not a reseatable local pointer you assign freely
L2

Advanced — this Pointer

const member functions and const this

  • In void show() const;, this has type like const Class* — you cannot modify members (except mutable).
  • Overload pairs: T& f(); and const T& f() const; for const-correct access.
  • Chaining on const objects needs const Class& return and const methods.
class Holder {
    int value = 0;
public:
    int& get() { return value; }
    const int& get() const { return value; } // this is const Class*
};

Returning this vs *this

  • return *this; → usually Class& for chaining on the object.
  • return this; → Class* when an API wants a pointer.
  • Do not return reference/pointer to a **local** — this refers to a stable object for the call, but the object must still be alive at the caller.

this and inheritance (preview)

  • In a base member function, this points to the whole object (including derived parts).
  • Virtual calls via this->f() still use dynamic dispatch when f is virtual.
  • Details deepen in Inheritance / Virtual Functions lessons.

Common pitfalls

  • Using this in a constructor carefully if the object is not fully built yet (especially virtual calls).
  • Storing this in a global/container after the object is destroyed → dangling.
  • Forgetting return *this; in a chaining method (returns void → cannot chain).
  • Trying to use this inside a static function.

Real-life models

  • Fluent form builder: form.name("Asha").age(20).submit(); using return *this;.
  • Game entity: enemy.takeDamage(5) uses this->health.
  • UI widget registers this with an event manager.
  • Setter style APIs in configuration objects.
L3

Tricky Interview Points

Q1) What is the this pointer in C++?

Answer An implicit pointer available in non-static member functions that points to the object on which the function was invoked.

Q2) Why is this needed?

Answer To identify the current object, disambiguate shadowed member names, return the object for chaining, and pass the object’s address to other APIs.

Q3) Does a static member function have this?

Answer No. Static member functions are not called on a specific instance, so there is no this pointer.

Q4) What is the difference between this and *this?

Answer this is a pointer to the current object; *this is the object itself (used when returning Class& for chaining).

Q5) How do you fix parameter names that clash with members?

Answer Assign with this->member = parameter; or rename the parameter.

Q6) How does method chaining work?

Answer A member function returns Class& (or Class*) via return *this (or return this) so the caller can call another method on the same object immediately.

Q7) What is the type of this in a const member function?

Answer It behaves like const Class* — you cannot modify non-mutable members through this.

Q8) Can you modify this to point to another object?

Answer No. this is provided by the language for the current call; you do not reseat it like a normal pointer variable.

Q9) Is this passed automatically?

Answer Yes. A call like obj.f(1) is implemented roughly like Class::f(&obj, 1).

Q10) Give a real-life analogy for this.

Answer “My” in “my notebook” — the notebook belonging to the current person/object.

Q11) When is storing this dangerous?

Answer If you save this beyond the object’s lifetime, you get a dangling pointer when the object is destroyed.

Q12) Can constructors use this?

Answer Yes for initializing members, but avoid relying on virtual calls through this before the object is fully constructed.

L4

Simple Programs

this-> for shadowed names

#include <iostream>
using namespace std;

class Demo {
    int n;
public:
    void set(int n) { this->n = n; }
    int get() const { return this->n; }
};

int main() {
    Demo d;
    d.set(42);
    cout << d.get() << "\n";
    return 0;
}

Method chaining with *this

#include <iostream>
using namespace std;

class Point {
    int x = 0, y = 0;
public:
    Point& setX(int v) { this->x = v; return *this; }
    Point& setY(int v) { this->y = v; return *this; }
    void show() const { cout << "(" << x << "," << y << ")\n"; }
};

int main() {
    Point p;
    p.setX(3).setY(4).show();
    return 0;
}

Show address of this

#include <iostream>
using namespace std;

class Node {
public:
    void where() {
        cout << "this = " << this << "\n";
    }
};

int main() {
    Node a, b;
    a.where();
    b.where(); // different this
    cout << "&a = " << &a << "\n";
    return 0;
}

Identity check with this

#include <iostream>
using namespace std;

class Item {
public:
    bool isSame(const Item& other) const {
        return this == &other;
    }
};

int main() {
    Item a, b;
    cout << a.isSame(a) << "\n"; // 1
    cout << a.isSame(b) << "\n"; // 0
    return 0;
}

Fluent Account API

#include <iostream>
using namespace std;

class Account {
    int balance = 0;
public:
    Account& deposit(int x) {
        if (x > 0) this->balance += x;
        return *this;
    }
    Account& withdraw(int x) {
        if (x > 0 && x <= balance) this->balance -= x;
        return *this;
    }
    void show() const { cout << balance << "\n"; }
};

int main() {
    Account acc;
    acc.deposit(1000).withdraw(250).show(); // 750
    return 0;
}

const method uses const this

#include <iostream>
using namespace std;

class Meter {
    int reading = 0;
public:
    void bump() { this->reading++; }
    int get() const { return this->reading; }
};

int main() {
    Meter m;
    m.bump();
    const Meter& view = m;
    cout << view.get() << "\n";
    return 0;
}
L5

Problem Solving Tricks

  • this points to the object used in obj.method(...).
  • Use this->member when names clash with parameters.
  • return *this; + Class& enables fluent chaining.
  • Static functions have no this — do not use it there.
  • In const methods, treat this as pointing to a const object.
  • Printing this helps you see each object’s identity while learning.
  • Prefer clear parameter names to reduce need for this-> — still know the pattern.
  • Do not store this longer than the object lives.
  • obj.f() secretly passes &obj as this.
  • Chain only methods that return *this (or a reference to the object).
  • Use this for callbacks/registration carefully (lifetime).
  • Read this->x as “this object’s x”.
L6

Practice Programs List

  1. Write setters that take parameters named like members; assign with this->.
  2. Build Point::setX/setY returning *this and chain three calls.
  3. Print this inside a method for two different objects; compare with &obj.
  4. Implement isSame(const T&) using this == &other.
  5. Create a fluent StringBuilder-like class append(...).append(...).show().
  6. Show a compile error by using this inside a static member function.
  7. Add a const getter and call it on a const object.
  8. Refactor bare member access to this-> in one class for clarity practice.
  9. Simulate a Team::add(Player*) where Player::join passes this.
  10. Write Account deposit/withdraw chaining and print final balance.
  11. Explain in comments why return *this uses a reference return type.
  12. Demonstrate shadowing bug (n = n) and the this-> fix.
  13. List five real APIs where method chaining is readable.
  14. Describe what this means during obj.f() vs ptr->f().