Рассмотрим следующую иерархию:
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; }
};
Какая точная структура памяти
C
экземпляра? Сколько в нем вптр, где именно каждый из них размещен? Какие из виртуальных таблиц используются совместно с виртуальной таблицей C? Что именно содержит каждая виртуальная таблица?Вот как я понимаю макет:
---------------------------------------------------------------- |vptr1 | AptrOfB1 | b1 | B2ptr | c | vptr2 | AptrOfB2 | b2 | a | ----------------------------------------------------------------
где
AptrOfBx
- указатель наA
экземпляр, который содержитBx
(поскольку наследование виртуальное).
Это правильно? На какие функции указываетvptr1
? На какие функции указываетvptr2
?Учитывая следующий код
C* c = new C(); dynamic_cast<B1*>(c)->f(3); static_cast<B2*>(c)->f(3); reinterpret_cast<B2*>(c)->f(3);
Почему все звонки
f
на печать33
?
C foo; intptr_t offsetB1 = (intptr_t)(B1*)&foo - (intptr_t)&foo;
, начало других баз может быть получено аналогично. Кроме того, вычислениеsizeof
всех классов должно дать вам еще одну хорошую подсказку. - person cmaster - reinstate monica   schedule 18.07.2014