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???? 
                        
We cannot pass the
Dpointer to a virtual function overridingB2::f2(), because all overrides of the same virtual function must accept identical memory layout.Since
B2::f2()function expectsB2's memory layout of the object being passed to it as itsthispointer, i.e.the overriding function
D::f2()must expect the same layout as well. Otherwise, the functions would no longer be interchangeable.To see why interchangeability matters consider this scenario:
B2::test()needs to make a call off2()in both scenarios. It has no additional information to tell it howthispointer has to be adjusted when making these calls*. That is why the compiler passes the fixed-up pointer, sotest()'s call off2would work both withD::f2()andB2::f2().* Other implementations may very well pass this information; however, multiple inheritance implementation discussed in the article does not do it.