C++
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C++
-
Section 4: Memory Management
-
Section 5: Templates and Generic Programming
-
Section 6: The Standard Template Library
-
Section 7: Modern C++ Features
-
Section 8: Error Handling
-
Section 9: Multithreading
-
Section 10: Operator Overloading and Type Conversion
-
Section 11: Advanced Topics
-
Section 12: Tooling and Build Systems
-
Section 13: Design Patterns in C++
-
Section 14: Interfacing with C and Systems Programming
-
Section 15: Networking and IPC Basics
-
Section 16: Graphics and Game Programming Basics
-
Section 17: The Boost Libraries
-
Section 18: Data Structures and Algorithms in C++
-
Section 19: Practical Projects
-
Section 20: More Concurrency Patterns
-
Section 21: More OOP and Design Practice
-
Section 22: File I/O and Streams
-
Section 23: More Standard Library
-
Section 24: Practice Exercises
-
Section 25: Interview and Algorithm Practice
-
Section 26: Compiler and Language Internals
-
Section 27: GUI and Application Frameworks Overview
-
Section 28: Testing and Quality Practices
-
Section 29: Numerics Library
-
Section 30: Concepts Library (C++20)
-
Section 31: Ranges Library (C++20) In Depth
-
Section 32: More Utility Library
41: The this Pointer
Wait, what exactly is this and where does it come from?
Think of this as a hidden secret that C++ keeps from you until you actually need it. Whenever you call a member function on an object, the compiler secretly passes the address of that object into the function. this is simply the name of that pointer.
If you have a Player object and you call player.takeDamage(10), the takeDamage function needs to know which player is taking damage. Since the function is shared by all instances of the class, this tells the code: "Operate on the specific instance that called me."
struct Player {
int health = 100;
void printAddress() {
// 'this' is a pointer to the current object
std::cout << "My address in memory is: " << this << std::endl;
}
};
Do I really need it if I just name my variables differently?
Technically, no. You could name your member variables m_health or _health to avoid naming collisions. But in the real world, you'll often see constructors or setters where the parameter name is exactly the same as the member variable. This is called "shadowing."
When the parameter name and the member name are identical, the compiler assumes you're talking about the parameter because it's "closer" in scope. To tell the compiler, "No, I mean the variable that belongs to this class," you use this->.
class Player {
private:
std::string name;
int level;
public:
// 'name' and 'level' here shadow the member variables
void setStats(std::string name, int level) {
this->name = name; // 'this->name' is the member, 'name' is the parameter
this->level = level; // Without 'this->', you'd just be assigning the parameter to itself
}
};
How do I use it to chain methods together?
This is where this becomes actually powerful. You've probably seen "fluent interfaces" in other languages—where you can chain calls like object.doA().doB().doC(). In C++, you achieve this by returning a reference to the current object using return *this;.
I personally love this for configuration objects. Instead of calling five different setter methods on five different lines, you can just flow them together. Note that we return a reference (Player&) rather than a copy, otherwise we'd be chaining calls on a temporary object that disappears instantly.
class Player {
int health = 100;
int mana = 100;
int strength = 10;
public:
Player& setHealth(int h) {
health = h;
return *this; // Return the object itself
}
Player& setMana(int m) {
mana = m;
return *this;
}
Player& setStrength(int s) {
strength = s;
return *this;
}
};
// Now you can do this:
Player p;
p.setHealth(80).setMana(50).setStrength(20);
📋 Practical Task
Exercise: Implementing a Fluent Character Customizer
You are building a character creation system for an RPG. Create a class called Character with the following requirements:
- Private members:
std::string name,int age, andstd::string characterClass. - A constructor that takes no arguments (initialize them to empty/zero).
- Three "setter" methods:
setName(),setAge(), andsetClass(). - Each setter must use
this->to resolve naming conflicts (meaning your parameters should have the exact same names as your member variables). - Each setter must return a reference to the
Characterobject to allow method chaining. - A
display()method that prints all the character's details to the console.
In your main() function, instantiate one Character and use a single line of chained method calls to set the name, age, and class before calling display().
There are no comments for now.