JKop said:
"plus one word for the vtable of every base class..."
BULLSHIT.
Andrew Koenig might choose not to dignify your rude and
unsubstantiated assertion with a reply, but for the sake of
discussion, let's pretend you had instead asked a polite
question like,
"Really? Why would an object need to contain multiple
vtable pointers?"
Suppose you have a derived class C with two bases A and B, as
follows:
class A {
int data;
public:
virtual ~A() {}
};
class B {
int data;
public:
virtual ~B() {}
};
class C : public A, public B
{
};
Now let's say we have some code like this:
A* a = new A;
delete a;
How does the delete statement work? Typically, the code at
the call site expects the object at the address specified by
'a' to have a certain memory layout, including a vtable
pointer which it can use to invoke the virtual destructor.
Now what if we write the following instead?
A* a = new C;
delete a;
Let's assume the compiler can't figure out the dynamic type of
*a through static analysis. It needs to be able to treat the
variable 'a' as if it pointed to an actual 'A' object. Thus,
'a' needs to contain the address of something with the same
memory layout as an actual 'A' object including the vtable
pointer (so the destructor can be invoked virtually).
Now if instead we write:
B* b = new C;
delete b;
Now the code at the call site can assume that 'b' is the address
of an actual 'B' object, i.e., something with the memory layout
expected of a 'B' object including the vtable pointer. In other
words, it points to the B subobject of the 'C' object. Since C
contains two sobobjects, each with its own vtable pointer,
it follows that each instance of 'C' has two vtable pointers.
This can be easily confirmed:
int main()
{
C c;
printf(
"sizeof(C)==%d &c==%p\n"
"sizeof(A)==%d (A*)&c==%p\n"
"sizeof(B)==%d (B*)&c==%p\n\n",
(int)sizeof(C), &c,
(int)sizeof(A), (A*)&c,
(int)sizeof(B), (B*)&c);
return 0;
}
Output (actually addresses may change, obviously):
sizeof(C)==16 &c==0012FF68
sizeof(A)==8 (A*)&c==0012FF68
sizeof(B)==8 (B*)&c==0012FF70
If C had only one vtable pointer you would expect its size
to be 12 (this being a 32-bit system).
Disclaimer: we're talking about typical implementations here,
not behavior specifically dictated by the standard.
--Nick