Помислете за следната йерархия:
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
екземпляр? Колко vptrs съдържа, къде точно е поставен всеки от тях? Кои от виртуалните таблици се споделят с виртуалната таблица на 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