Виртуальные таблицы и макет памяти в множественном виртуальном наследовании

Рассмотрим следующую иерархию:

struct A {
   int a; 
   A() { f(0); }
   A(int i) { f(i); }
   virtual void f(int i) { cout << i; }
};
struct B1 : virtual A {
   int b1;
   B1(int i) : A(i) { f(i); }
   virtual void f(int i) { cout << i+10; }
};
struct B2 : virtual A {
   int b2;
   B2(int i) : A(i) { f(i); }
   virtual void f(int i) { cout << i+20; }
};
struct C : B1, virtual B2 {
   int c;
   C() : B1(6),B2(3),A(1){}
   virtual void f(int i) { cout << i+30; }
};

What's the exact memory layout of C instance? How many vptrs it contains, where exactly each of them is placed? Which of virtual tables are shared with virtual table of C? What exactly each virtual table contains?

Here how I understand the layout:

----------------------------------------------------------------
|vptr1 | AptrOfB1 | b1 | B2ptr | c | vptr2 | AptrOfB2 | b2 | a |
----------------------------------------------------------------

where AptrOfBx is the pointer to A instance that Bx contains (since the inheritance is virtual).
Is that correct? Which functions vptr1 points to? Which functions vptr2 points to?

Given the following code

C* c = new C();
dynamic_cast<B1*>(c)->f(3);
static_cast<B2*>(c)->f(3);
reinterpret_cast<B2*>(c)->f(3);

Why all the calls to f print 33?

Ответы на вопрос(2)

Ваш ответ на вопрос