Consider following hierarchy:
struct A {
int a;
A() { f(0); }
A(int i) { f(i); }
virtual void f(int i) { cout << i; }
};
struct B1 : virtu
I have pimped your code a bit as follows:
#include
#include
struct A {
int a;
A() : a(32) { f(0); }
A(int i) : a(32) { f(i); }
virtual void f(int i) { printf("%d\n", i); }
};
struct B1 : virtual A {
int b1;
B1(int i) : A(i), b1(33) { f(i); }
virtual void f(int i) { printf("%d\n", i+10); }
};
struct B2 : virtual A {
int b2;
B2(int i) : A(i), b2(34) { f(i); }
virtual void f(int i) { printf("%d\n", i+20); }
};
struct C : B1, virtual B2 {
int c;
C() : B1(6),B2(3),A(1), c(35) {}
virtual void f(int i) { printf("%d\n", i+30); }
};
int main() {
C foo;
intptr_t address = (intptr_t)&foo;
printf("offset A = %ld, sizeof A = %ld\n", (intptr_t)(A*)&foo - address, sizeof(A));
printf("offset B1 = %ld, sizeof B1 = %ld\n", (intptr_t)(B1*)&foo - address, sizeof(B1));
printf("offset B2 = %ld, sizeof B2 = %ld\n", (intptr_t)(B2*)&foo - address, sizeof(B2));
printf("offset C = %ld, sizeof C = %ld\n", (intptr_t)(C*)&foo - address, sizeof(C));
unsigned char* data = (unsigned char*)address;
for(int offset = 0; offset < sizeof(C); offset++) {
if(!(offset & 7)) printf("| ");
printf("%02x ", (int)data[offset]);
}
printf("\n");
}
As you see, this prints quite a bit of additional information that allows us to deduce the memory layout. The output on my machine (a 64-bit linux, little endian byte order) is this:
1
23
16
offset A = 16, sizeof A = 16
offset B1 = 0, sizeof B1 = 32
offset B2 = 32, sizeof B2 = 32
offset C = 0, sizeof C = 48
| 00 0d 40 00 00 00 00 00 | 21 00 00 00 23 00 00 00 | 20 0d 40 00 00 00 00 00 | 20 00 00 00 00 00 00 00 | 48 0d 40 00 00 00 00 00 | 22 00 00 00 00 00 00 00
So, we can describe the layout as follows:
+--------+----+----+--------+----+----+--------+----+----+
| vptr | b1 | c | vptr | a | xx | vptr | b2 | xx |
+--------+----+----+--------+----+----+--------+----+----+
Here, xx denotes padding. Note how the compiler has placed the variable c into the padding of its non-virtual base. Note also, that all three v-pointers are different, this allows the program to deduce the correct positions of all the virtual bases.