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- |
|
✓ Yes |
✗ No |
|
|
✗ 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 |
|
Method Chaining |
Return |
|
Return Current Object |
Often in assignment operators |
|
Obtaining Address |
Pass current object pointer |
|
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
thisis a pointer to the current object*thisis a reference to the current object (dereferenced pointer)When returning for method chaining, use
*thisand 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:
✓
thisis an implicit pointer to the current object✓ Available in all non-static member functions
✓ Type is
ClassName* constorconst ClassName* const✓ Used for disambiguation, method chaining, and obtaining object address
✓ Return
*this(by reference) for method chaining✓
thispointer 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!