lucas clemente
lucas clemente

Reputation: 6389

Strange behavior of 'this' with inheritance

I'm having trouble understanding the value of this in the following example:

struct A {
  int i;

  void bar() {
    cout << this << endl;
  }
};

struct B : public A {
  virtual void foo() = 0;
};

struct C : public B {
  void foo() {
    printf("hello world!\n");
  }
};

int main (int argc, const char* argv[]) {
  C* c = new C; 
  cout << c << endl;
  c->bar();
  return 0;
}

Both times I print the pointer to the console, I get different values. I would expect it to be the same, as they refer to the same instance both times?!

If I remove either the virtual function or the int i in A it goes away. Why?

Upvotes: 2

Views: 99

Answers (2)

Hans Passant
Hans Passant

Reputation: 941873

It is a compiler optimization. The A struct doesn't have any virtual methods so it doesn't need a v-table. No point storing a pointer to it in an object of type A. Which makes the object layout different between objects of type A and C since C does need a v-table. The compiler makes up the difference by incrementing this before calling a method of A.

Add an arbitrary virtual method to A to make the pointers match.

Upvotes: 2

Loki Astari
Loki Astari

Reputation: 264531

But it refers to differnt things.

void bar() {
    cout << this << endl;
  }

Here this has a type A*. It points to the part of the object that is A.

out << c << endl;

Here c is a C* and points to the part of the object that is C.

If the A object lines up exactly with the C object the pointers are the same. If they do not (like when C contains other members (hidden pointer to the vtable) and thus the 'A' part is offset from the start of the larger object) then the pointers are not necessarily the same.

Upvotes: 2

Related Questions