Why siszeof(A) is 1 and sizeof(C) is 1 too ?
The function in C
is not virtual, so the class doesn't need a vtable pointer, so it needs no more storage than A
. Neither A
nor C
need any storage at all, but because language requires that different instances of the same class have different pointers, they can't have a size of zero - so the compiler makes them as small as it can, i.e. 1 byte.
Why siszeof(H) is 16 but sizeof(G) is 4 ?
G
has no virtual functions, so all it needs to store is the int, which on your compiler and architecture is 4 bytes.
H
has virtual functions, so the class needs to contain an int
and a vtable pointer. All widely used compilers store the vtable pointer at the start of the class, so the layout is {vptr, int}, which is 8+4=12 bytes if you're on a 64 bit host.
However, the compiler is free to pad this out to 16 bytes so that if multiple instances of H
are allocated in an array then all of them will be word-aligned. This is important because there are significant performance implications for accessing a pointer (i.e. the vtable pointer here) if it is not word-aligned.
Why siszeof(E) is 16 but sizeof(F) is 4 ?
E has virtual functions, so needs a vtable ptr, so its layout is just like H
's. F
has no virtual functions, it only has an int, so its layout is just like G
's. so the answer's the same as for G
and H
.
The ordering of the members/functions just doesn't matter here because there's only one member variable and the vtable ptr always goes first if there is one.
Why siszeof(D) is 8 but sizeof(E) is 16 ?
D
has no member variables, but it has a virtual function, so it needs a vtable pointer. The vtable pointer is the only thing it needs, so its size is sizeof(void*)
, which is 8 bytes. E
needs the same as D
, plus 4 bytes for an integer, and the compiler rounds it up to 16 bytes for alignment.