The this Pointer

The this pointer is an implicit pointer available in every non-static member function that points to the object on which the method was called.

What is the this Pointer?

Definition: In every non-static method, the compiler implicitly passes a hidden pointer named this that points to the current object.

Important

When you write:

object.method();

It is conceptually equivalent to:

ClassName::method(&object);

Inside the method, this is a pointer to the object that invoked the function.

Why Methods Can Access Object Attributes

You might wonder: how do multiple objects of the same class share the same method code, yet each method call operates on different object data?

Answer: The this pointer is the mechanism that allows methods to know which object’s attributes to access.

Note

Key insight: All objects of a class share the same method code (there’s no duplication). The this pointer is how methods know which specific object’s attributes to access.

Basic Usage Example

class Point {
private:
    double x_;
    double y_;

public:
    Point(double x, double y) : x_{x}, y_{y} {}

    void move(double dx, double dy) {
        this->x_ += dx;  // Explicitly using this
        this->y_ += dy;  // Explicitly using this
    }

    void print() const {
        std::cout << "(" << this->x_ << ", " << this->y_ << ")\n";
    }
};

Tip

In the example above, this->x_ is equivalent to just x_. The this-> prefix is optional in most cases but can improve clarity.

Type of the this Pointer

The type of this depends on whether the method is const or not:

Context

Type of this

Can modify object?

Can reassign this?

Non-const method

ClassName* const

✓ Yes

✗ No

const method

const ClassName* const

✗ No

✗ No

Important

The this pointer itself is always const (you cannot change what it points to), but whether you can modify the object depends on whether the method is const.

Example:

class Point {
private:
    double x_;

public:
    // Non-const method: this has type Point* const
    void set_x(double x) {
        this->x_ = x;  // ✓ Can modify object
        // this = nullptr;  // ❌ Error: cannot reassign this
    }

    // const method: this has type const Point* const
    double get_x() const {
        // this->x_ = 5.0;  // ❌ Error: cannot modify object
        return this->x_;    // ✓ Can read object
    }
};

When and Why to Use this

There are four primary use cases for the this pointer:

1. Disambiguation

When a parameter name shadows (has the same name as) a member variable.

class Point {
private:
    double x_;
    double y_;

public:
    Point(double x, double y) : x_{x}, y_{y} {}

    // Using this for disambiguation
    void set_coordinates(double x, double y) {
        this->x_ = x;  // Clear: member variable = parameter
        this->y_ = y;  // Without this->, compiler error or confusion
    }
};

Tip

While member initializer lists handle this in constructors, this-> is useful in setter methods when parameter names match member names.

2. Method Chaining

Returning *this allows multiple method calls to be chained together.

class Counter {
private:
    int value_;

public:
    Counter(int v = 0) : value_{v} {}

    Counter& increment() {
        ++value_;
        return *this;  // Return reference to current object
    }

    Counter& decrement() {
        --value_;
        return *this;
    }

    Counter& reset() {
        value_ = 0;
        return *this;
    }

    void print() const {
        std::cout << "Value: " << value_ << '\n';
    }
};

int main() {
    Counter c;
    c.increment().increment().increment().print();  // Value: 3
    c.reset().increment().increment().print();      // Value: 2
}

Note

Method chaining requires returning *this (a reference to the current object), not this (a pointer).

3. Returning the Current Object

Often used in operator overloading (covered in Lecture 9).

class Point {
private:
    double x_, y_;

public:
    Point(double x, double y) : x_{x}, y_{y} {}

    // Assignment operator (preview for Lecture 9)
    Point& operator=(const Point& other) {
        if (this != &other) {  // Self-assignment check
            x_ = other.x_;
            y_ = other.y_;
        }
        return *this;
    }
};

4. Obtaining Address

Sometimes you need to pass the current object’s address to another function.

class Node {
private:
    int data_;
    Node* next_;

public:
    Node(int data) : data_{data}, next_{nullptr} {}

    void set_next(Node* node) {
        next_ = node;
    }

    void append_self_to(Node* other) {
        other->set_next(this);  // Pass pointer to current object
    }
};

Common Use Cases Summary

Purpose

Description

Example

Disambiguation

When parameter shadows member variable

this->x_ = x;

Method Chaining

Return *this for fluent interface

return *this;

Return Current Object

Often in assignment operators

return *this;

Obtaining Address

Pass current object pointer

return this;

this Pointer vs. *this

Understanding the difference:

class Example {
public:
    Example* get_pointer() {
        return this;   // Returns pointer to object
    }

    Example& get_reference() {
        return *this;  // Returns reference to object (dereferenced pointer)
    }

    Example get_copy() {
        return *this;  // Returns copy of object
    }
};

Warning

  • this is a pointer to the current object

  • *this is a reference to the current object (dereferenced pointer)

  • When returning for method chaining, use *this and return by reference

Complete Example: Fluent Interface

Here’s a practical example combining multiple this pointer concepts:

class StringBuilder {
private:
    std::string content_;

public:
    StringBuilder() = default;

    // Method chaining with this
    StringBuilder& append(const std::string& text) {
        content_ += text;
        return *this;
    }

    StringBuilder& append_line(const std::string& text) {
        content_ += text + "\n";
        return *this;
    }

    StringBuilder& clear() {
        content_.clear();
        return *this;
    }

    [[nodiscard]] const std::string& str() const noexcept {
        return content_;
    }
};

int main() {
    StringBuilder sb;
    std::string result = sb.append("Hello ")
                           .append("World")
                           .append_line("!")
                           .append("Welcome to C++")
                           .str();

    std::cout << result << '\n';
    // Output:
    // Hello World!
    // Welcome to C++
}

Common Mistakes

Warning

Critical Errors:

❌ Trying to reassign this

void method() {
    this = nullptr;  // ❌ Error: this is const pointer!
}

❌ Returning this instead of *this for chaining

Counter* increment() {
    ++value_;
    return this;  // ❌ Returns pointer, not reference!
}

❌ Forgetting & in return type for chaining

Counter increment() {  // ❌ Returns copy, not reference!
    ++value_;
    return *this;
}

❌ Using this in static methods

static void static_method() {
    this->x_ = 5;  // ❌ Error: static methods have no this!
}

Best Practices

Important

Guidelines for using this:

✓ Use this-> for disambiguation when parameters shadow members

✓ Return *this (by reference) for method chaining

✓ Use this (pointer) when passing current object address

✓ Avoid unnecessary this-> prefix when no ambiguity exists

✓ Remember this is unavailable in static methods

Tip

Modern C++ style often omits this-> when there’s no ambiguity, but using it explicitly can improve code clarity, especially for beginners or in complex classes.

const-Correctness and this

The const qualifier on a method affects the type of this:

class Example {
private:
    int value_;

public:
    // Non-const method: this is Example* const
    void modify() {
        this->value_ = 42;  // ✓ OK
    }

    // const method: this is const Example* const
    void read() const {
        // this->value_ = 42;  // ❌ Error: cannot modify through const this
        int x = this->value_;  // ✓ OK: can read
    }
};

Summary

The this Pointer Checklist:

  • this is an implicit pointer to the current object

  • ✓ Available in all non-static member functions

  • ✓ Type is ClassName* const or const ClassName* const

  • ✓ Used for disambiguation, method chaining, and obtaining object address

  • ✓ Return *this (by reference) for method chaining

  • this pointer itself cannot be reassigned

  • ✓ Unavailable in static methods

Note

The this pointer is fundamental to understanding how C++ implements object-oriented programming. It’s the hidden mechanism that makes methods work on specific object instances!