Virtual Tableについて

/*
Vtable for B1
B1::_ZTV2B1: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI2B1)
16    B1::f1

Class B1
   size=16 align=8
   base size=16 base align=8
B1 (0x7ff8afb7ad90) 0
    vptr=((& B1::_ZTV2B1) + 16u)
 */
class B1 {
public:
    void f0(){}
    virtual void f1(){}
    char before_b0_char;
    int member_b1;
};
/*
Class B0
   size=4 align=4
   base size=4 base align=4
B0 (0x7ff8afb7e1c0) 0
 */
class B0{
private:
    void f(){};
    int member_b1;
};
/*
Vtable for B2
B2::_ZTV2B2: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI2B2)
16    B2::f2

Class B2
   size=16 align=8
   base size=13 base align=8
B2 (0x7ff8afb7e2a0) 0
    vptr=((& B2::_ZTV2B2) + 16u)

*/
class B2 {
public:
    virtual void f2(){}
    int member_b2;
    char member_b2_char;
};

/*
Vtable for Sub
Sub::_ZTV3Sub: 8u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI3Sub)
16    B1::f1
24    Sub::f2
32    Sub::d:
40    (int (*)(...))-0x00000000000000010
48    (int (*)(...))(& _ZTI3Sub)
56    Sub::_ZThn16_N3Sub2f2Ev

Class Sub
   size=40 align=8
   base size=36 base align=8
Sub (0x7ff8afb83000) 0
    vptr=((& Sub::_ZTV3Sub) + 16u)
  B1 (0x7ff8afb7e5b0) 0
      primary-for Sub (0x7ff8afb83000)
  B2 (0x7ff8afb7e620) 16
      vptr=((& Sub::_ZTV3Sub) + 56u)

*/
class Sub : public B1,public B2{
public:
    virtual void f2(){}
    virtual void d(){}
    int member_sub;
};

struct X : B1 , B2 {
    char x_char;
};
#include <iostream>

using namespace std;

int main(){
    //sizeof b0 :4
    cout << "sizeof b0 :" << sizeof(B0) << endl;
    //sizeof b1 :16
    cout << "sizeof b1 :" << sizeof(B1) << endl;
    //sizeof b2 :16
    cout << "sizeof b2 :" << sizeof(B2) << endl;
    //sizeof sub:40
    cout << "sizeof sub:" << sizeof(Sub) << endl;
    //sizeof X 32
    cout << "sizeof X  :" << sizeof(X) << endl; 
}