Skip to Content
Course content
Click on the "Edit" button in the top corner of the screen to edit your slide content.

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, and std::string characterClass.
  • A constructor that takes no arguments (initialize them to empty/zero).
  • Three "setter" methods: setName(), setAge(), and setClass().
  • 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 Character object 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().

Rating
0 0

There are no comments for now.

to be the first to leave a comment.