-2

questions:

  1. in the code below, the 'this' pointer points to different things in base and derived classes, even though it technically contains the same address. why is that.
  2. what is happening when the 'this' pointer is used with inheritance. (any help would be appreciated. thanks.)
#include <iostream>
using namespace std;

// this pointer and inheritance.
class base {
public:
  int x;
  base() {
    x = 10;
  }
  void func() {
    cout<< this->x << endl; // 10
    cout<< this << endl;
  }
};
class derived : public base {
public:
  int x;
  derived() {
    x = 20;
  }
  void func() {
    cout<< this->x << endl; // 20
    cout<< this << endl;
    base::func();
  }
};

int main () {
  derived d;
  d.func();

  cout<< "execution complete.\n";
  return 0;
}
output:
20
0x61ff18
10
0x61ff18
execution complete.
  • 1
    Related, if not a duplicate: https://stackoverflow.com/questions/44410120/warning-on-derived-class-member-shadowing-base-class-member – πάντα ῥεῖ May 18 '22 at 15:12
  • `derived` has 2 `x` here. – Jarod42 May 18 '22 at 15:13
  • 1. it points to the same thing, the instance `derived d;` in your `main`; then you see 10 and 20, because your `int x;` is shadowed in the derived class; 2. nothing special – pptaszni May 18 '22 at 15:15
  • `struct x {int y;}; x z;` // &z and &z.y are the same address but point to different things – user253751 May 18 '22 at 15:18
  • Both questions "How does the 'this' pointer work?" and "What is happening when the 'this' pointer is used?" are probably too broad for Stack Overflow. It seems that your understanding is incomplete, and you are trying to ask us to explain aspects of C++ until your understanding feels sufficiently complete. I think what's needed is a more specific question. – Drew Dormann May 18 '22 at 15:31
  • In your code a `derived` IS - from a design perspective - a `base`, and that translates to meaning a `derived *` IS a `base *` (although the reverse is not true). Printing `this` as you are converts it to `void *`, which is the address in memory - and (in your case) that address is for the first byte in memory of your object. Since, in your example, the `this` pointers are both for the same object, printing them gives the same address. [A tougher thing to explain would be what happens if your derived class has multiple bases - in that case, what happens is compiler dependent]. – Peter May 18 '22 at 15:41
  • The real question is: How does `this` work with multiple inheritance? – Goswin von Brederlow May 18 '22 at 16:39

3 Answers3

2
  1. in the code below, the 'this' pointer points to different things in base and derived classes, even though it technically contains the same address. why is that.

Classes contain subobjects. They can be base-subobjects or non-static data members. The first sub-object can share the memory address of the encapsulating complete object:

|derived  |  < complete object
|base|x   |  < sub objects of derived
|x   |       < sub objects of base sub object

^
|
same address    
  1. what is happening when the 'this' pointer is used with inheritance.

If you call a non-static member function of a class, this points to the instance argument within that function.

If you call a non-virtual non-static member function of a base of a derived object, this will point to the base sub object within that function.

If you call a virtual non-static member function of a class using unqualified lookup, it will call the most derived override of that function and this within that function will point to the object where that function is derived.

eerorika
  • 232,697
  • 12
  • 197
  • 326
2

Your class derived contains two integers. They have the names:

this->base::x

and

this->derived::x

What you seem to be discovering is that you can simply type this->x to refer to one of those integers.

The compiler will decide which x you are referring to by context. Inside the base class, you must mean this->base::x. Inside the derived class, it is assumed that you mean this->derived::x and you would need to explicitly write this->base::x to tell the compiler that you are referring to the int x; defined in base.

the 'this' pointer points to different things in base and derived classes

That is not true.

this does not point to different things in base and derived. It is the same this.

The meaning of this->x changes, because your class has two variables both named x.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
0

The derived class in your program has a member function named func that hides the inherited member function with the same name from base. Similarly, the derived class also a data member named x that hides the inherited data member with the same name from base.

Now, when you wrote:

d.func(); //this calls the derived class member function `func` implicitly passing the address of `d` to the implicit `this` parameter

In the above call, you're calling the derived class' member function func meanwhile implicitly passing the address of d to the implicit this parameter. The type of this inside func of derived is derived*.

Now, inside the member function func of derived the expression this->x uses the data member x of the derived class(and not the inherited member x) because as explained above, it hides the inherited member from base. Thus we get the output 20.

Next, cout<< this << endl; just prints this.

Next, the call expression base::func() is encountered. Also note that base::func() is equivalent to writing this->base::func(). This has the effect that it calls the inherited member function named func that was hidden due to the derived class having a function with the same name. Note in this call also, the same address is passed to the implicit this parameter of func of base class. The difference this time is that, this inside base's member function func is of type base*.

Now, inside the member function func of base, the x in the expression this->x refers to the base class' data member x and hence prints the value 10. Thus we get the output 10.

Finally, we have cout<< this << endl; inside base's member function func, which just prints the this.

Jason
  • 36,170
  • 5
  • 26
  • 60