I'm reading this article "Virtual method table"
Example in the above article:
class B1 {
public:
void f0() {}
virtual void f1() {}
int int_in_b1;
};
class B2 {
public:
virtual void f2() {}
int int_in_b2;
};
class D : public B1, public B2 {
public:
void d() {}
void f2() {} // override B2::f2()
int int_in_d;
};
B2 *b2 = new B2();
D *d = new D();
In the article, the author introduces that the memory layout of object d
is like this:
d:
D* d--> +0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
B2* b2--> +8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d
Total size: 20 Bytes.
virtual method table of D (for B1):
+0: B1::f1() // B1::f1() is not overridden
virtual method table of D (for B2):
+0: D::f2() // B2::f2() is overridden by D::f2()
The question is about d->f2()
. The call to d->f2()
passes a B2
pointer as a this
pointer so we have to do something like:
(*(*(d[+8]/*pointer to virtual method table of D (for B2)*/)[0]))(d+8) /* Call d->f2() */
Why should we pass a B2
pointer as the this
pointer not the original D
pointer??? We are actually calling D::f2(). Based on my understanding, we should pass a D
pointer as this
to D::f2() function.
___update____
If passing a B2
pointer as this
to D::f2(), What if we want to access the members of B1
class in D::f2()?? I believe the B2
pointer (this) is shown like this:
d:
D* d--> +0: pointer to virtual method table of D (for B1)
+4: value of int_in_b1
B2* b2--> +8: pointer to virtual method table of D (for B2)
+12: value of int_in_b2
+16: value of int_in_d
It already has a certain offset of the beginning address of this contiguous memory layout. For example, we want to access b1
inside D::f2(), I guess in runtime, it will do something like: *(this+4)
(this
points to the same address as b2) which would points b2
in B
????
B2
pointer asthis
to D::f2(), what if we want to access the members of B1 class in D::f2()? For (2), please see the update of the question. – Taranto