Why does `*this` resolve to the subclass?

Viewed 53
// Example program
#include <iostream>
#include <string>

class A;
class B;

void h(A &a) { std::cout << "a"; }
void h(B &b) { std::cout << "b"; }

class A {
    public:
    virtual void call() { h(*this); }
};

class B: public A {
    public:
    void call() override { h(*this); }
};

int main()
{
  B b = B{};
  A &test = b;
  
  h(test); // prints a
  test.call(); // prints b
}

I was messing around with code for a bit and noticed that *this always seemed to know which subclass it was, whereas normally we "lose information" when we initialize a subclass as a superclass object.

What exactly is going on behind the scenes to make h(*this) call h(B &b) instead of h(A &a)? What are the two calls in main doing differently such that one prints a, and the other prints b?

1 Answers
h(test); // prints a

Since the type of test is A &, that's the overload that gets called. There's nothing more to say here. The End. The books are closed on this subject matter, and this is the compiler's job to do, here. The compiler figures out which overload to call based on what test is.

test.call();

This invokes test's virtual method. Since test is actually B, this calls B's overridden virtual method. That's how virtual methods work in C++.

Guess what happens in B?

void call() override { h(*this); }

Since the type of *this is B &, that's the overload that gets called. There's nothing more to say here. The End. The books are closed on this subject matter, and this is the compiler's job to do here. The compiler figures out which overload to call based on what *this is.

Related